You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
4.3 KiB
C#

using System;
using Unity.BossRoom.Gameplay.UserInput;
using Unity.BossRoom.Gameplay.GameplayObjects;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using Unity.Netcode;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Unity.BossRoom.Gameplay.Actions
{
public partial class TargetAction
{
private GameObject m_TargetReticule;
private ulong m_CurrentTarget;
private ulong m_NewTarget;
private const float k_ReticuleGroundHeight = 0.2f;
public override bool OnStartClient(ClientCharacter clientCharacter)
{
base.OnStartClient(clientCharacter);
clientCharacter.serverCharacter.TargetId.OnValueChanged += OnTargetChanged;
clientCharacter.serverCharacter.GetComponent<ClientInputSender>().ActionInputEvent += OnActionInput;
return true;
}
private void OnTargetChanged(ulong oldTarget, ulong newTarget)
{
m_NewTarget = newTarget;
}
public override bool OnUpdateClient(ClientCharacter clientCharacter)
{
if (m_CurrentTarget != m_NewTarget)
{
m_CurrentTarget = m_NewTarget;
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(m_CurrentTarget, out NetworkObject targetObject))
{
var targetEntity = targetObject != null ? targetObject.GetComponent<ITargetable>() : null;
if (targetEntity != null)
{
ValidateReticule(clientCharacter, targetObject);
m_TargetReticule.SetActive(true);
var parentTransform = targetObject.transform;
if (targetObject.TryGetComponent(out ServerCharacter serverCharacter) && serverCharacter.clientCharacter)
{
//for characters, attach the reticule to the child graphics object.
parentTransform = serverCharacter.clientCharacter.transform;
}
m_TargetReticule.transform.parent = parentTransform;
m_TargetReticule.transform.localPosition = new Vector3(0, k_ReticuleGroundHeight, 0);
}
}
else
{
// null check here in case the target was destroyed along with the target reticule
if (m_TargetReticule != null)
{
m_TargetReticule.transform.parent = null;
m_TargetReticule.SetActive(false);
}
}
}
return true;
}
/// <summary>
/// Ensures that the TargetReticule GameObject exists. This must be done prior to enabling it because it can be destroyed
/// "accidentally" if its parent is destroyed while it is detached.
/// </summary>
void ValidateReticule(ClientCharacter parent, NetworkObject targetObject)
{
if (m_TargetReticule == null)
{
m_TargetReticule = Object.Instantiate(parent.TargetReticulePrefab);
}
bool target_isnpc = targetObject.GetComponent<ITargetable>().IsNpc;
bool myself_isnpc = parent.serverCharacter.CharacterClass.IsNpc;
bool hostile = target_isnpc != myself_isnpc;
m_TargetReticule.GetComponent<MeshRenderer>().material = hostile ? parent.ReticuleHostileMat : parent.ReticuleFriendlyMat;
}
public override void CancelClient(ClientCharacter clientCharacter)
{
GameObject.Destroy(m_TargetReticule);
clientCharacter.serverCharacter.TargetId.OnValueChanged -= OnTargetChanged;
if (clientCharacter.TryGetComponent(out ClientInputSender inputSender))
{
inputSender.ActionInputEvent -= OnActionInput;
}
}
private void OnActionInput(ActionRequestData data)
{
//this method runs on the owning client, and allows us to anticipate our new target for purposes of FX visualization.
if (GameDataSource.Instance.GetActionPrototypeByID(data.ActionID).IsGeneralTargetAction)
{
m_NewTarget = data.TargetIds[0];
}
}
}
}