added: full logic and ability for downing and picking up allies
This commit is contained in:
@@ -24,7 +24,7 @@ namespace Reset.Core {
|
||||
//EndAction can be called from anywhere.
|
||||
protected override void OnExecute(){
|
||||
try {
|
||||
agent.SetTrigger("trigger");
|
||||
agent.SetTrigger(trigger.value);
|
||||
} catch (Exception e) {
|
||||
Debug.LogError($"Did not set Network Animator trigger <i>{trigger.name}</i> on <b>{(agent == null ? null : agent.name)}</b>: {e.Message}");
|
||||
}
|
||||
|
||||
@@ -27,32 +27,29 @@ namespace Reset.Units {
|
||||
//This is called once each time the task is enabled.
|
||||
//Call EndAction() to mark the action as finished, either in success or failure.
|
||||
//EndAction can be called from anywhere.
|
||||
protected override void OnExecute() {
|
||||
protected override void OnExecute(){
|
||||
Unit targetUnit = target.value.GetComponent<Unit>();
|
||||
|
||||
try {
|
||||
if (targetUnit != null) {
|
||||
if (target.value.GetComponent<Unit>().UnitIsNetworked()) {
|
||||
targetUnit.DoGraphEventRpc(eventToSend);
|
||||
} else {
|
||||
targetUnit.GetComponent<GraphOwner>().SendEvent("eventToSend");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Debug.LogError($"Failed to send event {eventToSend} to {target}: {e.Message}");
|
||||
}
|
||||
|
||||
EndAction(true);
|
||||
}
|
||||
|
||||
//Called once per frame while the action is active.
|
||||
protected override void OnUpdate(){
|
||||
try {
|
||||
if (target.value.GetComponent<Unit>().UnitIsNetworked()) {
|
||||
ulong targetID = (target.value.GetComponent<NetworkObject>()).NetworkObjectId;
|
||||
|
||||
|
||||
SendEventRpc(agent.RpcTarget.Single(targetID, RpcTargetUse.Temp));
|
||||
} else {
|
||||
target.value.GetComponent<GraphOwner>().SendEvent("eventToSend");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Debug.LogError($"Failed to send event {eventToSend} to {target}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[Rpc(SendTo.SpecifiedInParams)]
|
||||
void SendEventRpc(RpcParams rpcParams = default){
|
||||
target.value.GetComponent<GraphOwner>().SendEvent("eventToSend");
|
||||
Debug.Log("");
|
||||
}
|
||||
|
||||
//Called when the task is disabled.
|
||||
protected override void OnStop() {
|
||||
|
||||
|
||||
@@ -6,3 +6,4 @@ public interface IInteractable{
|
||||
public void CancelInteract();
|
||||
public void OnObserverDetected(EnvironmentObserver observer);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Drawing;
|
||||
using Reset;
|
||||
using Reset.Core;
|
||||
using Reset.Core.Tools;
|
||||
using Reset.Units;
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Serialization;
|
||||
using UnityEngine;
|
||||
using Unity.Netcode;
|
||||
|
||||
namespace Reset.Units{
|
||||
public class Player : Unit, IKillable{
|
||||
public class Player : Unit, IKillable, IInteractable{
|
||||
[HideInInspector] public PlayerControls controls;
|
||||
|
||||
public float maxHealth{ get; set; }
|
||||
public float currentHealth{ get; set; }
|
||||
|
||||
float IKillable.maxHealth{ get; set; }
|
||||
float IKillable.currentHealth{ get; set; }
|
||||
public NetworkVariable<bool> _isDowned;
|
||||
|
||||
public bool IsDowned => _isDowned.Value;
|
||||
|
||||
private float timeDowned;
|
||||
|
||||
public GameObject pickupTarget;
|
||||
|
||||
void Awake(){
|
||||
controls = GetComponent<PlayerControls>();
|
||||
maxHealth = 20f;
|
||||
}
|
||||
|
||||
public void Attach(){
|
||||
@@ -47,6 +51,14 @@ namespace Reset.Units{
|
||||
|
||||
public override void UnitUpdate(){
|
||||
GetComponent<IKillable>().DrawHealthDebug();
|
||||
|
||||
if (IsDowned) {
|
||||
timeDowned += 1f * Time.deltaTime;
|
||||
}
|
||||
|
||||
if (timeDowned > 5f) {
|
||||
Kill();
|
||||
}
|
||||
}
|
||||
|
||||
public void TakeDamage(DamageSource[] sources){
|
||||
@@ -58,14 +70,107 @@ namespace Reset.Units{
|
||||
public void TakeDamage(DamageSource source){
|
||||
((IKillable)this).currentHealth -= source.damageDealt;
|
||||
|
||||
if (UnitIsNetworked()) {
|
||||
SetNewHealthRpc(currentHealth);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// TODO: Move somewhere not stupid so there's not an identical method in Enemy.cs
|
||||
[Rpc(SendTo.Everyone)]
|
||||
public void SetNewHealthRpc(float health){
|
||||
currentHealth = health;
|
||||
|
||||
// NOTE: only here for testing. Move out of here into some "post damage" check method
|
||||
if (((IKillable)this).currentHealth <= 0) {
|
||||
Kill();
|
||||
// if (UnitIsNetworked()) {
|
||||
Down();
|
||||
// } else {
|
||||
// Kill();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public void Kill(){
|
||||
throw new NotImplementedException();
|
||||
public override void SetNewPosition(Vector3 position){
|
||||
var contr = GetComponent<CharacterController>();
|
||||
contr.enabled = false;
|
||||
|
||||
transform.position = position;
|
||||
|
||||
contr.enabled = true;
|
||||
}
|
||||
|
||||
public void Down(){
|
||||
Graph.SendEvent("Downed");
|
||||
}
|
||||
|
||||
public void Kill(){
|
||||
Graph.SendEvent("Killed");
|
||||
}
|
||||
|
||||
public void Interact(){
|
||||
// Check if the other player can be interacted with at all
|
||||
if (pickupTarget&& pickupTarget.GetComponent<Player>().CanInteract()) {
|
||||
// Tell the local player to start picking up the ally and switch states
|
||||
Graph.SendEvent("Picking Up Ally");
|
||||
|
||||
// Tell the target player to start getting picked up.
|
||||
pickupTarget.GetComponent<Player>().StartPickupRpc();
|
||||
|
||||
// Wait for the pickup timer to finish
|
||||
StartCoroutine(PickupTimer());
|
||||
}
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Owner)]
|
||||
public void StartPickupRpc(){
|
||||
// When picked up by another player, move into the pick up state
|
||||
// TODO: Turn all these send events into a goddamn task maybe? State stuff should happen in the state machine. Concurrent stuff should happen in code
|
||||
Graph.SendEvent("Pick Up Start");
|
||||
}
|
||||
|
||||
IEnumerator PickupTimer(){
|
||||
// Start a timer and wait for it to complete
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < 7f) {
|
||||
elapsed += 1f * Time.deltaTime;
|
||||
|
||||
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Graph.SendEvent("Pick Up Success");
|
||||
}
|
||||
|
||||
public bool CanInteract(){
|
||||
return IsDowned;
|
||||
}
|
||||
|
||||
public void CancelInteract(){
|
||||
Graph.SendEvent("Pick Up Failed");
|
||||
}
|
||||
|
||||
public void OnObserverDetected(EnvironmentObserver observer){
|
||||
// Try and get a Player component from the current hit object
|
||||
// The rest of the logic will continue as expected so long as an
|
||||
pickupTarget = observer.hit.collider.gameObject;
|
||||
DrawInteractStatus();
|
||||
}
|
||||
|
||||
void DrawInteractStatus(){
|
||||
using (Draw.WithColor(Color.blue)) {
|
||||
Draw.ingame.Label2D(transform.position + Vector3.up * 2.5f, "Interactable",
|
||||
Color.orchid);
|
||||
}
|
||||
}
|
||||
|
||||
void LateUpdate(){
|
||||
// Clear the pickupTarget every frame
|
||||
// NOTE: Will this work online?
|
||||
pickupTarget = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,8 @@ public class EnvironmentObserver{
|
||||
}
|
||||
|
||||
if (hit.transform != null) {
|
||||
if (hit.transform.GetComponent<IInteractable>() != null) {
|
||||
IInteractable interactable = hit.transform.GetComponent<IInteractable>();
|
||||
if (interactable != null && interactable.CanInteract()) {
|
||||
hit.transform.GetComponent<IInteractable>().OnObserverDetected(this);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -2,16 +2,54 @@
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
using Drawing;
|
||||
using NodeCanvas.BehaviourTrees;
|
||||
using NodeCanvas.Framework;
|
||||
using NodeCanvas.StateMachines;
|
||||
using Reset;
|
||||
using Reset.Units;
|
||||
using Unity.Collections;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Reset.Units{
|
||||
public class Unit : NetworkBehaviour{
|
||||
public class Unit : NetworkBehaviour, INetworkSerializeByMemcpy{
|
||||
|
||||
public string state;
|
||||
|
||||
public NetworkVariable<FixedString64Bytes> testSTate;
|
||||
|
||||
private FSMOwner fsm;
|
||||
|
||||
private UnitMovementHandler _movement;
|
||||
internal UnitMovementHandler Movement{
|
||||
get{
|
||||
if (!_movement) {
|
||||
_movement = GetComponent<UnitMovementHandler>();
|
||||
}
|
||||
|
||||
return _movement;
|
||||
}
|
||||
}
|
||||
|
||||
private GraphOwner _graph;
|
||||
internal GraphOwner Graph{
|
||||
get{
|
||||
if (!_graph) {
|
||||
_graph = GetComponent<GraphOwner>();
|
||||
}
|
||||
|
||||
return _graph;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake(){
|
||||
fsm = GetComponent<FSMOwner>();
|
||||
}
|
||||
|
||||
public virtual void Start(){
|
||||
UnitStart();
|
||||
}
|
||||
|
||||
|
||||
public virtual void UnitStart(){ }
|
||||
|
||||
@@ -36,10 +74,17 @@ namespace Reset.Units{
|
||||
|
||||
UnitUpdate();
|
||||
}
|
||||
|
||||
public virtual void SetNewPosition(Vector3 position){ }
|
||||
|
||||
public virtual void UnitUpdate(){ }
|
||||
|
||||
void UpdateGizmos(){
|
||||
DrawOnlineStatusGizmo();
|
||||
DrawStateGizmo();
|
||||
}
|
||||
|
||||
private void DrawOnlineStatusGizmo(){
|
||||
string onlineStatus = "Not Online";
|
||||
Color onlineColor = Color.gray;
|
||||
|
||||
@@ -55,10 +100,44 @@ namespace Reset.Units{
|
||||
|
||||
Draw.ingame.Label2D(transform.position + Vector3.up * 2.5f, onlineStatus, onlineColor);
|
||||
}
|
||||
|
||||
|
||||
private void DrawStateGizmo(){
|
||||
if (fsm && UnitIsLocal()) {
|
||||
testSTate.Value = fsm.currentRootStateName;
|
||||
// if (UnitIsNetworked()) {
|
||||
// // state = fsm.currentRootStateName;
|
||||
// SendStateInformationRpc(fsm.currentRootStateName);
|
||||
// } else {
|
||||
// state = fsm.currentRootStateName;
|
||||
// }
|
||||
} else {
|
||||
fsm = GetComponent<FSMOwner>();
|
||||
}
|
||||
|
||||
// state = state.ToString().ToUpper();
|
||||
|
||||
try {
|
||||
Draw.ingame.Label2D(transform.position + Vector3.up * 2.7f, testSTate.Value.ToString(), Color.red);
|
||||
} catch (Exception e) {
|
||||
Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Everyone)]
|
||||
public void SendStateInformationRpc(string newState){
|
||||
Debug.Log($"newstate! {newState}");
|
||||
state = newState;
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Owner)]
|
||||
public void TakeOwnershipRpc(ulong clientID){
|
||||
GetComponent<NetworkObject>().ChangeOwnership(clientID);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Owner)]
|
||||
public void DoGraphEventRpc(string eventToSend){
|
||||
Debug.Log(eventToSend);
|
||||
GetComponent<FSMOwner>().SendEvent(eventToSend); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user