Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Physics disable while interactions + UseMob fix for Gomez and Cooks + Walk fixes #347

Merged
merged 7 commits into from
Apr 28, 2024
10 changes: 9 additions & 1 deletion Assets/GothicVR-Lab/Scripts/Handler/LabNpcAnimationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,19 @@ public class LabNpcAnimationHandler : MonoBehaviour, ILabHandler

private Dictionary<string, List<(Type, AnimationAction)>> animations = new()
{
{
"Human - Wash self", new()
{
(typeof(PlayAni), new(string0: "T_STAND_2_WASH")),
(typeof(Wait), new(float0: 5)),
(typeof(PlayAni), new(string0: "T_WASH_2_STAND")),
}
},
{
"Human - Sword training", new()
{
(typeof(DrawWeapon), new()),
(typeof(PlayAni), new("T_1HSFREE"))
(typeof(PlayAni), new(string0: "T_1HSFREE"))
}
},
{"Human - Eat Apple", new()
Expand Down
5 changes: 3 additions & 2 deletions Assets/GothicVR/Scripts/Creator/AnimationCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private static bool TryPlayAnimation(string mdsName, string animationName, GameO
LookupCache.AnimationClipCache[mdsAnimationKeyName] = clip;

AddClipEvents(clip, modelAnimation, anim);
AddClipEndEvent(clip);
AddClipEndEvent(anim, clip);
}

if (animationComp[mdsAnimationKeyName] == null)
Expand Down Expand Up @@ -294,12 +294,13 @@ private static float ClampFrame(int expectedFrame, IModelAnimation modelAnimatio
/// @see: https://docs.unity3d.com/ScriptReference/AnimationEvent.html
/// @see: https://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html
/// </summary>
private static void AddClipEndEvent(AnimationClip clip)
private static void AddClipEndEvent(IAnimation anim, AnimationClip clip)
{
AnimationEvent finalEvent = new()
{
time = clip.length,
functionName = nameof(IAnimationCallbacks.AnimationEndCallback),
stringParameter = JsonUtility.ToJson(new SerializableEventEndSignal(anim.Next))
};

clip.AddEvent(finalEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ private void AddZsCollider()
for (var i = 0; i < zm.childCount; i++)
{
var child = zm.GetChild(i);
if (!child.name.StartsWithIgnoreCase("ZS"))
if (!child.name.StartsWithIgnoreCase("ZS_"))
continue;

// ZS need to be "invisible" for the Raycast teleporter.
child.gameObject.layer = Constants.IgnoreRaycastLayer;

child.localScale = Constants.VobZSScale;
// Used for event triggers with NPCs.
var coll = child.AddComponent<SphereCollider>();
coll.isTrigger = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using JetBrains.Annotations;

namespace GVR.Data.ZkEvents
{
/// <summary>
/// UnityEngine.JsonUtility doesn't serialize CachedEventTag. We therefore use this class to JSON-ify the data.
/// </summary>
public class SerializableEventEndSignal
{
public string NextAnimation;

public SerializableEventEndSignal([NotNull] string nextAnimation)
{
NextAnimation = nextAnimation;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions Assets/GothicVR/Scripts/Globals/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ public static class Constants
public static readonly Shader ShaderBarrier = Shader.Find("Unlit/Barrier");
public static readonly Shader ShaderThunder = Shader.Find("Unlit/ThunderShader");


public const float NpcWalkingSpeed = 1f;
public const float NpcRotationSpeed = 3f;

public const string SceneBootstrap = "Bootstrap";
public const string SceneGeneral = "General";
public const string SceneMainMenu = "MainMenu";
Expand All @@ -37,9 +33,7 @@ public static class Constants
// solves some weird interactions between the teleport raycast and collider (musicZone/worldTriggerChange)
public static LayerMask IgnoreRaycastLayer { get; set; } = LayerMask.NameToLayer("Ignore Raycast");

//Tags for components to exchange the default font with custom Gothic title and subtitle / ingame fonts
public const string MenuFontTag = "Title";
public const string SubtitleFontTag = "IngameText";
// Tags
public const string ClimbableTag = "Climbable";
public const string SpotTag = "PxVob_zCVobSpot";
public const string PlayerTag = "Player";
Expand All @@ -57,6 +51,8 @@ public static class Constants
public static string selectedWorld { get; set; } = "world.zen";
public static string selectedWaypoint { get; set; } = "START";

// We need to set the scale so that collision and NPC animation is starting at the right spot.
public static Vector3 VobZSScale = new(0.1f, 0.1f, 0.1f);

static Constants()
{
Expand Down
2 changes: 1 addition & 1 deletion Assets/GothicVR/Scripts/Manager/NpcHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public static int ExtNpcGetDistToWp(NpcInstance npc, string waypointName)

var waypoint = WayNetHelper.GetWayNetPoint(waypointName);

if (waypoint == null || npcGo)
if (waypoint == null || !npcGo)
return int.MaxValue;

return (int)Vector3.Distance(npcPos, waypoint.Position);
Expand Down
2 changes: 1 addition & 1 deletion Assets/GothicVR/Scripts/Manager/PhysicsHelper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using GVR.Properties;
using UnityEngine;

namespace GVR.GothicVR.Scripts.Manager
namespace GVR.Manager
{
public static class PhysicsHelper
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using GVR.Data.ZkEvents;
using GVR.Extensions;
using GVR.GothicVR.Scripts.Manager;
using GVR.Manager;
using GVR.Properties;
using UnityEngine;
using EventType = ZenKit.EventType;
Expand All @@ -25,8 +26,12 @@ public AbstractAnimationAction(AnimationAction action, GameObject npcGo)
NpcGo = npcGo;
Props = npcGo.GetComponent<NpcProperties>();
}

public abstract void Start();

public virtual void Start()
{
// By default every Daedalus aninmation starts without using physics. But they can always overwrite it (e.g.) for walking.
PhysicsHelper.DisablePhysicsForNpc(Props);
}

/// <summary>
/// We just set the audio by default.
Expand Down Expand Up @@ -83,16 +88,31 @@ protected virtual void InsertItem(string slot1, string slot2)

private void RemoveItem()
{
// Some animations need to force remove items, some not.
if (Props.usedItemSlot == "")
return;

var slotGo = NpcGo.FindChildRecursively(Props.usedItemSlot);
var item = slotGo!.transform.GetChild(0);

Object.Destroy(item.gameObject);
}

/// <summary>
/// Most of our animations are fine if we just set this flag and return it via IsFinished()
/// If an animation has also a next animation set, we will call it automatically.
/// If this is not intended, the overwriting class can always reset the animation being played at the same frame.
/// </summary>
public virtual void AnimationEndEventCallback()
public virtual void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
// e.g. T_STAND_2_WASH -> S_WASH -> S_WASH ... -> T_WASH_2_STAND
// Inside daedalus there is no information about S_WASH, but we need this animation automatically being played.
if (!eventData.NextAnimation.IsEmpty())
{
PhysicsHelper.DisablePhysicsForNpc(Props);
AnimationCreator.PlayAnimation(Props.mdsNames, eventData.NextAnimation, Props.go);
}

IsFinishedFlag = true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using GVR.Creator;
using GVR.Data.ZkEvents;
using GVR.Vm;
using UnityEngine;

Expand Down Expand Up @@ -77,9 +78,9 @@ private void HandleRotation(Transform npcTransform)
}
}

public override void AnimationEndEventCallback()
public override void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
base.AnimationEndEventCallback();
base.AnimationEndEventCallback(eventData);
IsFinishedFlag = false;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using GVR.Creator;
using GVR.Data.ZkEvents;
using GVR.Manager;
using GVR.Vm;
using UnityEngine;

Expand All @@ -25,7 +27,14 @@ protected AbstractWalkAnimationAction(AnimationAction action, GameObject npcGo)
/// We need to define the final destination spot within overriding class.
/// </summary>
protected abstract Vector3 GetWalkDestination();


public override void Start()
{
base.Start();

PhysicsHelper.EnablePhysicsForNpc(Props);
}

public override void Tick(Transform transform)
{
base.Tick(transform);
Expand Down Expand Up @@ -106,9 +115,13 @@ private void HandleRotation(Transform transform, Vector3 destination, bool inclu
/// <summary>
/// We need to alter rootNode's position once walk animation is done.
/// </summary>
public override void AnimationEndEventCallback()
public override void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
base.AnimationEndEventCallback();
base.AnimationEndEventCallback(eventData);

// We need to ensure, that physics still apply when an animation is looped.
if (walkState != WalkState.Done)
PhysicsHelper.EnablePhysicsForNpc(Props);

NpcGo.transform.localPosition = Props.bip01.position;
Props.bip01.localPosition = Vector3.zero;
Expand Down
36 changes: 24 additions & 12 deletions Assets/GothicVR/Scripts/Npc/Actions/AnimationActions/GoToFp.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using GVR.Data.ZkEvents;
using GVR.GothicVR.Scripts.Manager;
using GVR.Manager;
using GVR.Vob.WayNet;
using UnityEngine;
Expand All @@ -17,11 +19,16 @@ public GoToFp(AnimationAction action, GameObject npcGo) : base(action, npcGo)

public override void Start()
{
var pos = NpcGo.transform.position;
base.Start();

fp = WayNetHelper.FindNearestFreePoint(pos, destination);
var npcPos = NpcGo.transform.position;
fp = WayNetHelper.FindNearestFreePoint(npcPos, destination);

// Fix - If NPC is spawned directly in front of the FP, we start transition immediately (otherwise trigger/collider won't be called).
if (Vector3.Distance(npcPos, fp!.Position) < 1f)
FreePointReached();
}

public override void OnTriggerEnter(Collider coll)
{
if (walkState != WalkState.Walk)
Expand All @@ -30,18 +37,12 @@ public override void OnTriggerEnter(Collider coll)
if (coll.gameObject.name != fp.Name)
return;

Props.CurrentFreePoint = fp;
fp.IsLocked = true;

AnimationEndEventCallback();

walkState = WalkState.Done;
IsFinishedFlag = true;
FreePointReached();
}

public override void AnimationEndEventCallback()
public override void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
base.AnimationEndEventCallback();
base.AnimationEndEventCallback(eventData);

IsFinishedFlag = false;
}
Expand All @@ -50,5 +51,16 @@ protected override Vector3 GetWalkDestination()
{
return fp.Position;
}

private void FreePointReached()
{
Props.CurrentFreePoint = fp;
fp.IsLocked = true;

AnimationEndEventCallback(new SerializableEventEndSignal(nextAnimation: ""));

walkState = WalkState.Done;
IsFinishedFlag = true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GVR.Caches;
using GVR.Data.ZkEvents;
using UnityEngine;

namespace GVR.Npc.Actions.AnimationActions
Expand All @@ -15,6 +16,8 @@ public GoToNpc(AnimationAction action, GameObject npcGo) : base(action, npcGo)

public override void Start()
{
base.Start();

destinationTransform = LookupCache.NpcCache[otherIndex].transform;
}

Expand All @@ -24,11 +27,11 @@ protected override Vector3 GetWalkDestination()
}


public override void AnimationEndEventCallback()
public override void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
base.AnimationEndEventCallback();
base.AnimationEndEventCallback(eventData);

IsFinishedFlag = false;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using GVR.Data.ZkEvents;
using GVR.Manager;
using GVR.Vob.WayNet;
using GVR.World;
Expand All @@ -18,6 +19,8 @@ public GoToWp(AnimationAction action, GameObject npcGo) : base(action, npcGo)

public override void Start()
{
base.Start();

var currentWaypoint = Props.CurrentWayPoint ?? WayNetHelper.FindNearestWayPoint(Props.transform.position);
var destinationWaypoint = (WayPoint)WayNetHelper.GetWayNetPoint(destination);

Expand Down Expand Up @@ -65,9 +68,9 @@ protected override Vector3 GetWalkDestination()
return route.Peek().Position;
}

public override void AnimationEndEventCallback()
public override void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
base.AnimationEndEventCallback();
base.AnimationEndEventCallback(eventData);

IsFinishedFlag = false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GVR.Caches;
using GVR.Data.ZkEvents;
using UnityEngine;

namespace GVR.Npc.Actions.AnimationActions
Expand All @@ -21,9 +22,9 @@ protected override Quaternion GetRotationDirection()
// return new Vector3(0, temp.y, 0);
}

public override void AnimationEndEventCallback()
public override void AnimationEndEventCallback(SerializableEventEndSignal eventData)
{
base.AnimationEndEventCallback();
base.AnimationEndEventCallback(eventData);

IsFinishedFlag = false;
}
Expand Down
Loading