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

Bugfix/lab errors #351

Merged
merged 11 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
9 changes: 3 additions & 6 deletions Assets/GothicVR-Lab/Scripts/Handler/LabNpcDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@ public class LabNpcDialogHandler : MonoBehaviour, ILabHandler
{
public TMP_Dropdown animationsDropdown;
public GameObject bloodwynSlotGo;
public BloodwynInstanceId bloodwynInstanceId;
private string bloodwynInstanceId = "GRD_233_Bloodwyn";

public enum BloodwynInstanceId
{
Deu = 6596
}

private NpcInstance bloodwynInstance;
private string[] animations = {
Expand All @@ -34,13 +30,14 @@ public void Bootstrap()

BootstrapBloodwyn();
}


private void BootstrapBloodwyn()
{
var newNpc = PrefabCache.TryGetObject(PrefabCache.PrefabType.Npc);
newNpc.SetParent(bloodwynSlotGo);

var npcSymbol = GameData.GothicVm.GetSymbolByIndex((int)bloodwynInstanceId);
var npcSymbol = GameData.GothicVm.GetSymbolByName(bloodwynInstanceId);
bloodwynInstance = GameData.GothicVm.AllocInstance<NpcInstance>(npcSymbol!);
var properties = newNpc.GetComponent<NpcProperties>();
LookupCache.NpcCache[bloodwynInstance.Index] = properties;
Expand Down
21 changes: 10 additions & 11 deletions Assets/GothicVR-Lab/Scripts/LabBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,32 @@
using GVR.Manager;
using GVR.Manager.Settings;
using UnityEngine;
using UnityEngine.Serialization;

namespace GVR.GothicVR_Lab.Scripts
{
public class LabBootstrapper : MonoBehaviour
{
[Header("Bootstrapping")]
public bool bootLabMusicHandler;
public bool bootNpcHandler;
public bool bootLockableHandler;
public bool bootLadderHandler;
public bool bootAttachPointHandler;

public LabMusicHandler labMusicHandler;
public LabNpcDialogHandler npcDialogHandler;
public LabLockableLabHandler lockableLabHandler;
public LabLadderLabHandler ladderLabHandler;
public LabVobHandAttachPointsLabHandler vobHandAttachPointsLabHandler;
public LabNpcAnimationHandler labNpcAnimationHandler;

private bool isBooted;
private bool _isBooted;
/// <summary>
/// It's easiest to wait for Start() to initialize all the MonoBehaviours first.
/// </summary>
private void Update()
{
if (isBooted)
if (_isBooted)
return;
isBooted = true;
_isBooted = true;

GvrBootstrapper.BootGothicVR(SettingsManager.GameSettings.GothicIPath);

BootLab();

labNpcAnimationHandler.Bootstrap();
labMusicHandler.Bootstrap();
npcDialogHandler.Bootstrap();
Expand All @@ -44,6 +38,11 @@ private void Update()
vobHandAttachPointsLabHandler.Bootstrap();
}

private void BootLab()
{
NpcHelper.CacheHero();
}

private void OnDestroy()
{
GameData.Dispose();
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
3 changes: 3 additions & 0 deletions Assets/GothicVR/Scripts/Creator/Sounds/SoundCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ private enum BitDepth
[CanBeNull]
public static SoundData GetSoundArrayFromVfs(string name)
{
if (GameData.Vfs == null)
return null;

var node = GameData.Vfs.Find(name);
if (node == null)
return null;
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
7 changes: 6 additions & 1 deletion Assets/GothicVR/Scripts/Manager/NpcHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ static NpcHelper()
}

private static void GeneralSceneLoaded()
{
CacheHero();
}

public static void CacheHero()
{
var heroIndex = GameData.GothicVm.GlobalHero!.Index;
var playerGo = GameObject.FindWithTag(Constants.PlayerTag);
Expand Down Expand Up @@ -209,7 +214,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
1 change: 0 additions & 1 deletion Assets/GothicVR/Scripts/Manager/VobHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ public static AudioClip GetSoundClip(string soundName)

if (soundData == null)
{
Debug.LogError($"No .wav data returned for {soundName}");
return null;
}

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
Loading