working on charging and quick attacks
This commit is contained in:
@@ -34,7 +34,7 @@ namespace RebootReality.jelycho.Beacons {
|
||||
}
|
||||
|
||||
public int GetMaxBytes() {
|
||||
return 0;
|
||||
return sizeof(float) * 3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ namespace RebootReality.jelycho.Beacons {
|
||||
[SerializeField] float m_ConnectionRopeLength = 10.0f;
|
||||
[SerializeField] float m_BeaconSpawnRadius = 15.0f;
|
||||
|
||||
[SerializeField] float m_BeaconSpawnShakeIntensity = 1.0f;
|
||||
[SerializeField] float m_BeaconSpawnShakeRadius = 20.0f;
|
||||
[SerializeField] float m_BeaconSpawnShakeDuration = 1.0f;
|
||||
|
||||
protected override IActorData CreateActorData() {
|
||||
return new BaseManagerActorData();
|
||||
}
|
||||
@@ -52,6 +56,13 @@ namespace RebootReality.jelycho.Beacons {
|
||||
SpawnBeaconCommandData commandData = new SpawnBeaconCommandData();
|
||||
DataSerializationUtils.Deserialize(actorCommand.Data, ref commandData);
|
||||
RR.SpawnActor(m_BeaconPrefab, commandData.Position, Quaternion.identity);
|
||||
|
||||
if (RR.World.Context is WorldContext worldContext) {
|
||||
worldContext.FeedbacksManager.ShakeCamera(commandData.Position,
|
||||
m_BeaconSpawnRadius,
|
||||
m_BeaconSpawnShakeIntensity,
|
||||
m_BeaconSpawnShakeDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace RebootReality.jelycho.Beacons {
|
||||
[Range(0.0f, 1.0f)] public float growAmount = 0.5f;
|
||||
[SerializeField] public float growSpeed = 0.5f;
|
||||
|
||||
[SerializeField] public ParticleSystem m_GrowParticleSystem;
|
||||
|
||||
float m_CurrentGrowAmount = 0.0f;
|
||||
|
||||
void Update() {
|
||||
@@ -81,6 +83,8 @@ namespace RebootReality.jelycho.Beacons {
|
||||
m_CurrentGrowAmount = 0.0f;
|
||||
UpdateElements(m_CurrentGrowAmount);
|
||||
growAmount = 1.0f;
|
||||
|
||||
m_GrowParticleSystem.Play();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using RebootKit.Engine.Network;
|
||||
using System;
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Network;
|
||||
using RebootKit.Engine.Simulation;
|
||||
using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootReality.jelycho.Enemies {
|
||||
public class ZombieActorData : IActorData {
|
||||
@@ -15,11 +18,104 @@ namespace RebootReality.jelycho.Enemies {
|
||||
}
|
||||
}
|
||||
|
||||
public class ZombieActor : Actor {
|
||||
public interface IKillable {
|
||||
bool IsAlive();
|
||||
|
||||
float OnHit(Actor attacker, float damage);
|
||||
}
|
||||
|
||||
public class ZombieActor : Actor, IKillable {
|
||||
static readonly Logger s_Logger = new Logger(nameof(ZombieActor));
|
||||
|
||||
[SerializeField] Animator m_Animator;
|
||||
|
||||
[SerializeField] Collider[] m_RagdollColliders;
|
||||
[SerializeField] Rigidbody[] m_RagdollRigidbodies;
|
||||
|
||||
[SerializeField] Collider[] m_Hitboxes;
|
||||
|
||||
//
|
||||
// @MARK: Unity callbacks
|
||||
//
|
||||
void Awake() {
|
||||
SetRagdollLocal(false);
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Actor
|
||||
//
|
||||
protected override IActorData CreateActorData() {
|
||||
return new ZombieActorData();
|
||||
}
|
||||
|
||||
protected override void OnActorEventClient(ActorEvent actorEvent) {
|
||||
ZombieActorEvents zombieEvent = (ZombieActorEvents) actorEvent.EventID;
|
||||
|
||||
switch (zombieEvent) {
|
||||
case ZombieActorEvents.EnableRagdoll: {
|
||||
SetRagdollLocal(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Ragdoll
|
||||
//
|
||||
void EnableRagdoll() {
|
||||
SendActorEvent((byte)ZombieActorEvents.EnableRagdoll);
|
||||
}
|
||||
|
||||
void SetRagdollLocal(bool active) {
|
||||
foreach (Collider ragdollCollider in m_RagdollColliders) {
|
||||
ragdollCollider.enabled = active;
|
||||
}
|
||||
|
||||
foreach (Rigidbody ragdollRigidbody in m_RagdollRigidbodies) {
|
||||
ragdollRigidbody.isKinematic = !active;
|
||||
}
|
||||
|
||||
m_Animator.enabled = !active;
|
||||
|
||||
foreach (Collider hitbox in m_Hitboxes) {
|
||||
hitbox.enabled = !active;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: IKillable
|
||||
//
|
||||
public float Health { get; private set; } = 100.0f;
|
||||
|
||||
public bool IsAlive() {
|
||||
return Health > 0.0f;
|
||||
}
|
||||
|
||||
public float OnHit(Actor attacker, float damage) {
|
||||
if (!RR.IsServer()) {
|
||||
s_Logger.Error("OnHit can only be called on the server.");
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (!IsAlive()) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
s_Logger.Info($"Hit: {damage}");
|
||||
|
||||
Health -= damage;
|
||||
if (Health <= 0.0f) {
|
||||
s_Logger.Info("Die");
|
||||
EnableRagdoll();
|
||||
return damage - Mathf.Abs(Health);
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZombieActorEvents {
|
||||
None = 0x00,
|
||||
EnableRagdoll = 0x01
|
||||
}
|
||||
}
|
||||
3
Assets/jelycho/Code/Feedbacks.meta
Normal file
3
Assets/jelycho/Code/Feedbacks.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e17e27d5e3a403ca95f4b4bc3ef1352
|
||||
timeCreated: 1753936922
|
||||
140
Assets/jelycho/Code/Feedbacks/FeedbacksManagerActor.cs
Normal file
140
Assets/jelycho/Code/Feedbacks/FeedbacksManagerActor.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System.Collections.Generic;
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Network;
|
||||
using RebootKit.Engine.Simulation;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootReality.jelycho.Feedbacks {
|
||||
struct CameraShakeFeedback {
|
||||
public Vector3 center;
|
||||
public float radius;
|
||||
public float intensity;
|
||||
public float timer;
|
||||
|
||||
public static int GetMaxBytes() {
|
||||
return sizeof(float) * 3 + sizeof(float) * 3;
|
||||
}
|
||||
}
|
||||
|
||||
public class FeedbacksManagerActor : Actor {
|
||||
static readonly Logger s_Logger = new Logger(nameof(FeedbacksManagerActor));
|
||||
|
||||
List<CameraShakeFeedback> m_ActiveCameraShakes = new List<CameraShakeFeedback>();
|
||||
|
||||
//
|
||||
// @MARK: Camera shake
|
||||
//
|
||||
public void ShakeCamera(Vector3 center, float radius, float intensity, float duration) {
|
||||
if (!RR.IsServer()) {
|
||||
s_Logger.Error("ShakeCamera can only be called on the server.");
|
||||
return;
|
||||
}
|
||||
|
||||
FeedbacksCameraShakeEvent ev = new FeedbacksCameraShakeEvent {
|
||||
Feedback = new CameraShakeFeedback {
|
||||
center = center,
|
||||
radius = radius,
|
||||
intensity = intensity,
|
||||
timer = duration
|
||||
}
|
||||
};
|
||||
SendActorEvent((byte)FeedbacksManagerActorEvents.CameraShake, ref ev);
|
||||
}
|
||||
|
||||
public float GetShakeIntensityForPosition(Vector3 position) {
|
||||
if (m_ActiveCameraShakes.Count == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float intensity = 0.0f;
|
||||
|
||||
foreach (CameraShakeFeedback feedback in m_ActiveCameraShakes) {
|
||||
if (feedback.radius <= 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float distSquared = math.distancesq(feedback.center, position);
|
||||
float radiusSquared = feedback.radius * feedback.radius;
|
||||
|
||||
if (distSquared > radiusSquared) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float feedbackIntensity = Mathf.Lerp(0.0f,
|
||||
feedback.intensity,
|
||||
1.0f - (distSquared / radiusSquared));
|
||||
intensity = Mathf.Max(feedbackIntensity, intensity);
|
||||
}
|
||||
|
||||
return intensity;
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Actor
|
||||
//
|
||||
protected override IActorData CreateActorData() {
|
||||
return new NoActorData();
|
||||
}
|
||||
|
||||
public override void OnClientTick(float deltaTime) {
|
||||
for (int i = m_ActiveCameraShakes.Count - 1; i >= 0; i--) {
|
||||
CameraShakeFeedback feedback = m_ActiveCameraShakes[i];
|
||||
feedback.timer -= deltaTime;
|
||||
|
||||
if (feedback.timer <= 0.0f) {
|
||||
m_ActiveCameraShakes.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
m_ActiveCameraShakes[i] = feedback;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActorEventClient(ActorEvent actorEvent) {
|
||||
FeedbacksManagerActorEvents feedbackEvent = (FeedbacksManagerActorEvents)actorEvent.EventID;
|
||||
|
||||
switch (feedbackEvent) {
|
||||
|
||||
case FeedbacksManagerActorEvents.CameraShake: {
|
||||
FeedbacksCameraShakeEvent ev = new FeedbacksCameraShakeEvent();
|
||||
DataSerializationUtils.Deserialize(actorEvent.Data, ref ev);
|
||||
|
||||
if (ev.Feedback.timer > 0.0f) {
|
||||
m_ActiveCameraShakes.Add(ev.Feedback);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum FeedbacksManagerActorEvents : byte {
|
||||
None = 0x00,
|
||||
CameraShake = 0x01,
|
||||
}
|
||||
|
||||
struct FeedbacksCameraShakeEvent : IActorData {
|
||||
public CameraShakeFeedback Feedback;
|
||||
|
||||
public int GetMaxBytes() {
|
||||
return CameraShakeFeedback.GetMaxBytes();
|
||||
}
|
||||
|
||||
public void Serialize(NetworkBufferWriter writer) {
|
||||
writer.Write(Feedback.center);
|
||||
writer.Write(Feedback.radius);
|
||||
writer.Write(Feedback.intensity);
|
||||
writer.Write(Feedback.timer);
|
||||
}
|
||||
|
||||
public void Deserialize(NetworkBufferReader reader) {
|
||||
reader.Read(out Feedback.center);
|
||||
reader.Read(out Feedback.radius);
|
||||
reader.Read(out Feedback.intensity);
|
||||
reader.Read(out Feedback.timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c66663d8df214ee9b21785208a782cc0
|
||||
timeCreated: 1753936932
|
||||
@@ -1,53 +0,0 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Simulation;
|
||||
using RebootReality.jelycho.Player;
|
||||
|
||||
namespace RebootReality.jelycho.Items {
|
||||
public class EggChargeAction : IItemChargeAction {
|
||||
static readonly Logger s_Logger = new Logger(nameof(EggChargeAction));
|
||||
|
||||
public bool OnChargeStart(Actor user, ItemActor itemActor) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemActor.Config.itemType != ItemType.Egg) {
|
||||
s_Logger.Error($"Item {itemActor.name} is not an egg, cannot charge.");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_Logger.Info($"Begin charging egg: {itemActor.name} by {user.name}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnChargeUpdate(Actor user, ItemActor itemActor, float chargeProgress) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Here you can implement the logic for updating the charge progress, e.g. visual effects
|
||||
s_Logger.Info($"Charging egg: {itemActor.name} by {user.name}, progress: {chargeProgress * 100}%");
|
||||
}
|
||||
|
||||
public void OnChargeEnd(Actor user, ItemActor itemActor, float chargeProgress) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_Logger.Info($"Finished charging egg: {itemActor.name} by {user.name}, final progress: {chargeProgress * 100}%");
|
||||
}
|
||||
|
||||
public void OnChargeCancel(Actor user, ItemActor itemActor) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_Logger.Info($"Charging egg: {itemActor.name} by {user.name} was cancelled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Assets/jelycho/Code/Items/HeavySlashAttackChargeAttack.cs
Normal file
20
Assets/jelycho/Code/Items/HeavySlashAttackChargeAttack.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using RebootKit.Engine.Simulation;
|
||||
|
||||
namespace RebootReality.jelycho.Items {
|
||||
public class HeavySlashAttackChargeAttack : IItemChargeAction {
|
||||
public bool OnChargeStart(Actor user, ItemActor itemActor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnChargeUpdate(Actor user, ItemActor itemActor, float chargeProgress) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnChargeEnd(Actor user, ItemActor itemActor, float chargeProgress) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnChargeCancel(Actor user, ItemActor itemActor) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 281ce87013154d44872e7b170e4d375c
|
||||
timeCreated: 1753934000
|
||||
@@ -4,29 +4,41 @@ using RebootKit.Engine.Simulation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootReality.jelycho.Items {
|
||||
public enum ItemType {
|
||||
Neutral = 0,
|
||||
Egg = 1,
|
||||
Sword = 2,
|
||||
}
|
||||
|
||||
public interface IItemChargeAction {
|
||||
bool OnChargeStart(Actor user, ItemActor itemActor);
|
||||
void OnChargeUpdate(Actor user, ItemActor itemActor, float chargeProgress);
|
||||
void OnChargeEnd(Actor user, ItemActor itemActor, float chargeProgress);
|
||||
bool OnChargeUpdate(Actor user, ItemActor itemActor, float chargeProgress);
|
||||
bool OnChargeEnd(Actor user, ItemActor itemActor, float chargeProgress);
|
||||
void OnChargeCancel(Actor user, ItemActor itemActor);
|
||||
}
|
||||
|
||||
|
||||
public interface IItemQuickAttackAction {
|
||||
void Attack(Actor attacker, ItemActor itemActor);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ItemConfig {
|
||||
public ItemType itemType = ItemType.Neutral;
|
||||
public Sprite icon;
|
||||
|
||||
[MaxLength(32)] public string characterEquippedMountSlotName = "hand_right";
|
||||
|
||||
[Header("Character Animations Names")]
|
||||
public string idleAnimation;
|
||||
public string chargingAnimation;
|
||||
public string chargedUseAnimation;
|
||||
|
||||
public string[] quickAttacksAnimations;
|
||||
public string blockAnimation;
|
||||
|
||||
[Header("Quick Attack")]
|
||||
public bool canQuickAttack = false;
|
||||
[SerializeReference] public IItemQuickAttackAction quickAttackAction;
|
||||
|
||||
[Header("Block")]
|
||||
public bool canBlock = false;
|
||||
|
||||
[Header("Chargeable")]
|
||||
public bool isChargeable = false;
|
||||
public float minChargeDuration = 0.1f;
|
||||
public float minChargeDuration = 0.5f;
|
||||
public float maxChargeDuration = 1.0f;
|
||||
public float chargeCooldown = 1.0f;
|
||||
[SerializeReference] public IItemChargeAction chargeAction;
|
||||
|
||||
31
Assets/jelycho/Code/Items/ItemQuickAttackAction.cs
Normal file
31
Assets/jelycho/Code/Items/ItemQuickAttackAction.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using RebootKit.Engine.Simulation;
|
||||
using RebootReality.jelycho.Enemies;
|
||||
using RebootReality.jelycho.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootReality.jelycho.Items {
|
||||
public class ItemQuickAttackAction : IItemQuickAttackAction {
|
||||
static readonly Collider[] s_CollidersBuffer = new Collider[512];
|
||||
|
||||
public void Attack(Actor attacker, ItemActor itemActor) {
|
||||
PlayerActor playerActor = attacker as PlayerActor;
|
||||
if (playerActor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 attackPosition = playerActor.GetAttackPosition();
|
||||
|
||||
int count = Physics.OverlapSphereNonAlloc(attackPosition, 3.0f, s_CollidersBuffer);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (s_CollidersBuffer[i].TryGetComponent(out IKillable killable)) {
|
||||
Actor killableActor = killable as Actor;
|
||||
if (killableActor == attacker) {
|
||||
continue;
|
||||
}
|
||||
|
||||
playerActor.DealDamage(killable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/jelycho/Code/Items/ItemQuickAttackAction.cs.meta
Normal file
3
Assets/jelycho/Code/Items/ItemQuickAttackAction.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05afb452f53145848b90465de1a40e30
|
||||
timeCreated: 1753943558
|
||||
52
Assets/jelycho/Code/Items/SpawnBeaconChargeAction.cs
Normal file
52
Assets/jelycho/Code/Items/SpawnBeaconChargeAction.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Simulation;
|
||||
using RebootReality.jelycho.Player;
|
||||
using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootReality.jelycho.Items {
|
||||
public class SpawnBeaconChargeAction : IItemChargeAction {
|
||||
static readonly Logger s_Logger = new Logger(nameof(SpawnBeaconChargeAction));
|
||||
|
||||
public bool OnChargeStart(Actor user, ItemActor itemActor) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnChargeUpdate(Actor user, ItemActor itemActor, float chargeProgress) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnChargeEnd(Actor user, ItemActor itemActor, float chargeProgress) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RR.World.Context is WorldContext worldContext) {
|
||||
if (player.TryGetBeaconPosition(out Vector3 beaconPosition)) {
|
||||
worldContext.BaseManager.TrySpawnBeacon(beaconPosition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnChargeCancel(Actor user, ItemActor itemActor) {
|
||||
PlayerActor player = user as PlayerActor;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Simulation.Sensors;
|
||||
using RebootReality.jelycho.Main;
|
||||
using Unity.Cinemachine;
|
||||
@@ -10,7 +11,7 @@ namespace RebootReality.jelycho.Player {
|
||||
[AddComponentMenu(GameConsts.k_AddComponentMenu + "Player/First Person Camera")]
|
||||
public class FPPCamera : MonoBehaviour {
|
||||
[ConfigVar("fpp.camera.fov", 60.0f, "Field of view for the first person camera.")]
|
||||
static ConfigVar s_cameraFOV;
|
||||
static ConfigVar s_CameraFOV;
|
||||
|
||||
[Header("Base")]
|
||||
[field: SerializeField]
|
||||
@@ -22,10 +23,17 @@ namespace RebootReality.jelycho.Player {
|
||||
[field: SerializeField]
|
||||
public CinemachineCamera Camera { get; private set; }
|
||||
|
||||
CinemachineBasicMultiChannelPerlin m_BobbingNoiseComponent;
|
||||
|
||||
CinemachineBasicMultiChannelPerlin m_NoiseComponent;
|
||||
|
||||
[SerializeField] SignalSourceAsset m_BobbingNoiseSettings;
|
||||
[SerializeField] float m_BobbingFrequency = 0.5f;
|
||||
[SerializeField] float m_BobbingAmplitude = 0.75f;
|
||||
|
||||
float m_BobbingIntensity = 0.0f;
|
||||
|
||||
[SerializeField] SignalSourceAsset m_ShakeNoiseSettings;
|
||||
[SerializeField] float m_ShakeFrequency = 1.0f;
|
||||
[SerializeField] float m_ShakeAmplitude = 1.0f;
|
||||
|
||||
[Header("Picking")]
|
||||
[SerializeField] float m_PickDistance = 5.0f;
|
||||
@@ -46,16 +54,30 @@ namespace RebootReality.jelycho.Player {
|
||||
}
|
||||
|
||||
void Awake() {
|
||||
m_BobbingNoiseComponent =
|
||||
m_NoiseComponent =
|
||||
Camera.GetCinemachineComponent(CinemachineCore.Stage.Noise) as CinemachineBasicMultiChannelPerlin;
|
||||
Assert.IsNotNull(m_BobbingNoiseComponent);
|
||||
Assert.IsNotNull(m_NoiseComponent);
|
||||
|
||||
SetBobbing(0.0f);
|
||||
}
|
||||
|
||||
public void Tick() {
|
||||
Camera.Lens.FieldOfView = s_cameraFOV.FloatValue;
|
||||
Camera.Lens.FieldOfView = s_CameraFOV.FloatValue;
|
||||
// Camera.transform.localRotation = Quaternion.Euler(Pitch, 0f, 0f);
|
||||
|
||||
if (RR.World.Context is WorldContext worldContext) {
|
||||
float shakeIntensity = worldContext.FeedbacksManager.GetShakeIntensityForPosition(transform.position);
|
||||
|
||||
if (shakeIntensity > 0.0f) {
|
||||
m_NoiseComponent.NoiseProfile = m_ShakeNoiseSettings as NoiseSettings;
|
||||
m_NoiseComponent.AmplitudeGain = m_ShakeAmplitude * shakeIntensity;
|
||||
m_NoiseComponent.FrequencyGain = m_ShakeFrequency * shakeIntensity;
|
||||
} else {
|
||||
m_NoiseComponent.NoiseProfile = m_BobbingNoiseSettings as NoiseSettings;
|
||||
m_NoiseComponent.AmplitudeGain = m_BobbingAmplitude * m_BobbingIntensity;
|
||||
m_NoiseComponent.FrequencyGain = m_BobbingFrequency * m_BobbingIntensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Rotate(float x, float y) {
|
||||
@@ -73,8 +95,7 @@ namespace RebootReality.jelycho.Player {
|
||||
}
|
||||
|
||||
public void SetBobbing(float t) {
|
||||
m_BobbingNoiseComponent.AmplitudeGain = m_BobbingAmplitude * t;
|
||||
m_BobbingNoiseComponent.FrequencyGain = m_BobbingFrequency * t;
|
||||
m_BobbingIntensity = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Network;
|
||||
using RebootKit.Engine.Simulation;
|
||||
using RebootReality.jelycho.Enemies;
|
||||
using RebootReality.jelycho.Items;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
@@ -12,16 +13,6 @@ using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootReality.jelycho.Player {
|
||||
[Serializable]
|
||||
struct PlayerItemTypeHandsAnimationsConfig {
|
||||
public ItemType itemType;
|
||||
|
||||
// @TODO: Cache hashes for state names
|
||||
public string idle;
|
||||
public string charging;
|
||||
public string chargedUse;
|
||||
}
|
||||
|
||||
public class PlayerActor : Actor {
|
||||
static readonly Logger s_Logger = new Logger(nameof(PlayerActor));
|
||||
|
||||
@@ -62,15 +53,8 @@ namespace RebootReality.jelycho.Player {
|
||||
[Header("Animations")]
|
||||
[SerializeField] int m_HandsLayerIndex;
|
||||
|
||||
[SerializeField] PlayerItemTypeHandsAnimationsConfig[] m_ItemTypeHandsAnimations;
|
||||
[SerializeField] PlayerItemTypeHandsAnimationsConfig m_DefaultItemHandsAnimations;
|
||||
[SerializeField] string m_HandsIdleStateName = "Hands Locomotion";
|
||||
|
||||
[Header("Dragging")]
|
||||
[SerializeField] Transform m_DragGutStartPosition;
|
||||
[SerializeField] PhysicsObjectDragger m_PhysicsDragger;
|
||||
[SerializeField] FloatRange m_DragDistanceRange = new FloatRange(1.0f, 5.0f);
|
||||
|
||||
[Header("Beacon location picking")]
|
||||
[SerializeField] LayerMask m_BeaconPlacementLayerMask = 0;
|
||||
[SerializeField] float m_BeaconPlacementMaxDistance = 15.0f;
|
||||
@@ -95,9 +79,14 @@ namespace RebootReality.jelycho.Player {
|
||||
|
||||
ItemActor m_EquippedItem;
|
||||
|
||||
[SerializeField] float m_StartChargeDelay = 0.15f;
|
||||
|
||||
bool m_IsCharging;
|
||||
float m_ChargeTimer;
|
||||
|
||||
int m_QuickAttackComboCounter;
|
||||
float m_QuickAttackComboTimer;
|
||||
|
||||
public float3 LookDirection {
|
||||
get {
|
||||
float pitchRad = math.radians(-m_Camera.Pitch);
|
||||
@@ -178,27 +167,6 @@ namespace RebootReality.jelycho.Player {
|
||||
m_Locomotion.SetWishDirection(direction);
|
||||
}
|
||||
|
||||
public void StartDrag() {
|
||||
if (!m_IsSetupAsOwner) {
|
||||
s_Logger.Error("Cannot start dragging when not set up as owner.");
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject pickedGameObject = m_Camera.Sensor.Sense();
|
||||
if (pickedGameObject != null && pickedGameObject.TryGetComponent(out Rigidbody rigidbody)) {
|
||||
m_PhysicsDragger.Grab(rigidbody);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopDrag() {
|
||||
if (!m_IsSetupAsOwner) {
|
||||
s_Logger.Error("Cannot stop dragging when not set up as owner.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_PhysicsDragger.Drop();
|
||||
}
|
||||
|
||||
public void DropItem() {
|
||||
if (!m_IsSetupAsOwner) {
|
||||
s_Logger.Error("Cannot drop item when not set up as owner.");
|
||||
@@ -213,42 +181,6 @@ namespace RebootReality.jelycho.Player {
|
||||
}
|
||||
}
|
||||
|
||||
PlayerItemTypeHandsAnimationsConfig GetHandsAnimationsConfig(ItemType itemType) {
|
||||
foreach (PlayerItemTypeHandsAnimationsConfig config in m_ItemTypeHandsAnimations) {
|
||||
if (config.itemType == itemType) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
return m_DefaultItemHandsAnimations;
|
||||
}
|
||||
|
||||
void SetHandsIdleAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
PlayerItemTypeHandsAnimationsConfig animationsConfig =
|
||||
GetHandsAnimationsConfig(m_EquippedItem.Config.itemType);
|
||||
m_Animator.CrossFade(animationsConfig.idle, 0.0f, m_HandsLayerIndex);
|
||||
} else {
|
||||
m_Animator.CrossFade(m_HandsIdleStateName, 0.0f, m_HandsLayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SetChargingAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
PlayerItemTypeHandsAnimationsConfig animationsConfig =
|
||||
GetHandsAnimationsConfig(m_EquippedItem.Config.itemType);
|
||||
m_Animator.CrossFade(animationsConfig.charging, 0.0f, m_HandsLayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SetChargedUseAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
PlayerItemTypeHandsAnimationsConfig animationsConfig =
|
||||
GetHandsAnimationsConfig(m_EquippedItem.Config.itemType);
|
||||
m_Animator.CrossFade(animationsConfig.chargedUse, 0.0f, m_HandsLayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginPrimaryAction() {
|
||||
if (!m_IsSetupAsOwner) {
|
||||
s_Logger.Error("Cannot begin primary action when not set up as owner.");
|
||||
@@ -259,13 +191,42 @@ namespace RebootReality.jelycho.Player {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_EquippedItem.Config.chargeAction != null && m_EquippedItem.Config.isChargeable) {
|
||||
if (m_EquippedItem.Config.chargeAction.OnChargeStart(this, m_EquippedItem)) {
|
||||
m_IsCharging = true;
|
||||
m_ChargeTimer = 0.0f;
|
||||
SetChargingAnimation();
|
||||
m_IsCharging = false;
|
||||
m_ChargeTimer = 0.0f;
|
||||
|
||||
if (m_QuickAttackComboTimer <= 0.0f) {
|
||||
m_QuickAttackComboCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void HoldingPrimaryAction() {
|
||||
if (!m_IsSetupAsOwner) {
|
||||
s_Logger.Error("Cannot begin primary action when not set up as owner.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_EquippedItem == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemConfig itemConfig = m_EquippedItem.Config;
|
||||
|
||||
if (!m_IsCharging && itemConfig.isChargeable && m_EquippedItem.Config.chargeAction != null ) {
|
||||
m_ChargeTimer += Time.deltaTime;
|
||||
|
||||
if (m_ChargeTimer >= m_StartChargeDelay) {
|
||||
if (itemConfig.chargeAction.OnChargeStart(this, m_EquippedItem)) {
|
||||
SetChargingAnimation();
|
||||
m_IsCharging = true;
|
||||
m_ChargeTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IsCharging) {
|
||||
m_ChargeTimer += Time.deltaTime;
|
||||
itemConfig.chargeAction.OnChargeUpdate(this, m_EquippedItem, GetChargeProgress());
|
||||
}
|
||||
}
|
||||
|
||||
float GetChargeProgress() {
|
||||
@@ -285,6 +246,10 @@ namespace RebootReality.jelycho.Player {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_EquippedItem == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_IsCharging) {
|
||||
ItemConfig itemConfig = m_EquippedItem.Config;
|
||||
|
||||
@@ -298,6 +263,14 @@ namespace RebootReality.jelycho.Player {
|
||||
}
|
||||
|
||||
m_IsCharging = false;
|
||||
} else if (m_EquippedItem.Config.canQuickAttack) {
|
||||
PlayQuickAttackAnimation(m_QuickAttackComboCounter);
|
||||
m_QuickAttackComboCounter += 1;
|
||||
m_QuickAttackComboTimer = 2.0f;
|
||||
|
||||
if (m_EquippedItem.Config.quickAttackAction != null) {
|
||||
m_EquippedItem.Config.quickAttackAction.Attack(this, m_EquippedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,9 +299,68 @@ namespace RebootReality.jelycho.Player {
|
||||
Pickup(itemActor);
|
||||
} else if (m_TargetInteractable.Value is not null) {
|
||||
m_TargetInteractable.Value.Interact();
|
||||
// SetAnimatorTriggerRpc(AnimatorParamHashes.Throw);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Hands animations
|
||||
//
|
||||
void PlayHandsAnimation(string animationName) {
|
||||
int hash = Animator.StringToHash(animationName);
|
||||
|
||||
if (!m_Animator.HasState(m_HandsLayerIndex, hash)) {
|
||||
s_Logger.Error($"Animator does not have state with name {animationName}");
|
||||
return;
|
||||
}
|
||||
|
||||
PlayHandsAnimation(hash);
|
||||
}
|
||||
|
||||
void PlayHandsAnimation(int animationHash) {
|
||||
m_Animator.CrossFade(animationHash, 0.0f, m_HandsLayerIndex);
|
||||
|
||||
if (RR.IsServer()) {
|
||||
PlayerPlayHandsAnimationEvent handsAnimationEvent = new PlayerPlayHandsAnimationEvent {
|
||||
AnimationHash = animationHash
|
||||
};
|
||||
SendActorEvent((byte)PlayerActorEvents.PlayHandsAnimation, ref handsAnimationEvent);
|
||||
} else {
|
||||
PlayerActorRequestHandsAnimationCommand handsAnimationCommand =
|
||||
new PlayerActorRequestHandsAnimationCommand {
|
||||
AnimationHash = animationHash
|
||||
};
|
||||
SendActorCommand((byte) PlayerActorCommands.RequestHandsAnimation, ref handsAnimationCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void SetHandsIdleAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
PlayHandsAnimation(m_EquippedItem.Config.idleAnimation);
|
||||
} else {
|
||||
PlayHandsAnimation(m_HandsIdleStateName);
|
||||
}
|
||||
}
|
||||
|
||||
void SetChargingAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
PlayHandsAnimation(m_EquippedItem.Config.chargingAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
void SetChargedUseAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
PlayHandsAnimation(m_EquippedItem.Config.chargedUseAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayQuickAttackAnimation(int combo) {
|
||||
if (m_EquippedItem == null || m_EquippedItem.Config.quickAttacksAnimations.Length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
string animationName = m_EquippedItem.Config.quickAttacksAnimations[combo % m_EquippedItem.Config.quickAttacksAnimations.Length];
|
||||
PlayHandsAnimation(animationName);
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Actor
|
||||
@@ -347,10 +379,9 @@ namespace RebootReality.jelycho.Player {
|
||||
TickCamera();
|
||||
UpdateAnimator(m_Locomotion.Velocity);
|
||||
SenseInteractable();
|
||||
|
||||
if (m_IsCharging) {
|
||||
m_ChargeTimer += deltaTime;
|
||||
m_EquippedItem.Config.chargeAction.OnChargeUpdate(this, m_EquippedItem, GetChargeProgress());
|
||||
|
||||
if (m_QuickAttackComboTimer > 0.0f) {
|
||||
m_QuickAttackComboTimer -= deltaTime;
|
||||
}
|
||||
|
||||
m_SyncRemoteStateTimer -= deltaTime;
|
||||
@@ -429,6 +460,39 @@ namespace RebootReality.jelycho.Player {
|
||||
Inventory.TryDrop(command.InventorySlotIndex, out _);
|
||||
break;
|
||||
}
|
||||
|
||||
case PlayerActorCommands.RequestHandsAnimation: {
|
||||
PlayerActorRequestHandsAnimationCommand command = new PlayerActorRequestHandsAnimationCommand();
|
||||
DataSerializationUtils.Deserialize(actorCommand.Data, ref command);
|
||||
|
||||
if (m_Animator.HasState(m_HandsLayerIndex, command.AnimationHash)) {
|
||||
PlayerPlayHandsAnimationEvent handsAnimationEvent = new PlayerPlayHandsAnimationEvent {
|
||||
AnimationHash = command.AnimationHash
|
||||
};
|
||||
SendActorEvent((byte)PlayerActorEvents.PlayHandsAnimation, ref handsAnimationEvent);
|
||||
} else {
|
||||
s_Logger.Error($"Animator does not have state with hash {command.AnimationHash}");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PlayerActorCommands.DealDamage: {
|
||||
PlayerActorDealDamageCommand dealDamageCommand = new PlayerActorDealDamageCommand();
|
||||
DataSerializationUtils.Deserialize(actorCommand.Data, ref dealDamageCommand);
|
||||
|
||||
Actor targetActor = RR.FindSpawnedActor(dealDamageCommand.TargetActorID);
|
||||
if (targetActor == null) {
|
||||
s_Logger.Error($"Target actor with ID {dealDamageCommand.TargetActorID} not found.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetActor is IKillable killable) {
|
||||
killable.OnHit(this, 100.0f);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,6 +553,22 @@ namespace RebootReality.jelycho.Player {
|
||||
break;
|
||||
}
|
||||
|
||||
case PlayerActorEvents.PlayHandsAnimation: {
|
||||
if (RR.IsServer()) {
|
||||
break;
|
||||
}
|
||||
|
||||
PlayerPlayHandsAnimationEvent handsAnimationEvent = new PlayerPlayHandsAnimationEvent();
|
||||
DataSerializationUtils.Deserialize(actorEvent.Data, ref handsAnimationEvent);
|
||||
|
||||
if (m_Animator.HasState(m_HandsLayerIndex, handsAnimationEvent.AnimationHash)) {
|
||||
m_Animator.CrossFade(handsAnimationEvent.AnimationHash, 0.0f, m_HandsLayerIndex);
|
||||
} else {
|
||||
s_Logger.Error($"Animator does not have state with hash {handsAnimationEvent.AnimationHash}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
s_Logger.Error("Invalid actor event received: " + actorEvent.EventID);
|
||||
break;
|
||||
@@ -543,6 +623,17 @@ namespace RebootReality.jelycho.Player {
|
||||
}
|
||||
}
|
||||
|
||||
public void DealDamage(IKillable target) {
|
||||
if (target is Actor actor) {
|
||||
PlayerActorDealDamageCommand dealDamageCommand = new PlayerActorDealDamageCommand {
|
||||
TargetActorID = actor.ActorID
|
||||
};
|
||||
SendActorCommand((byte)PlayerActorCommands.DealDamage, ref dealDamageCommand);
|
||||
} else {
|
||||
s_Logger.Error($"Player can only deal damage to other actors!");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Remote
|
||||
//
|
||||
@@ -640,7 +731,7 @@ namespace RebootReality.jelycho.Player {
|
||||
|
||||
if (m_EquippedItem != null) {
|
||||
m_EquippedItem.SetHidden(false);
|
||||
m_EquippedItem.MountTo(this, "hand_right");
|
||||
m_EquippedItem.MountTo(this, m_EquippedItem.Config.characterEquippedMountSlotName);
|
||||
}
|
||||
|
||||
PlayerActorPrimaryEquippedItemChangedEvent itemChangedEvent =
|
||||
@@ -709,7 +800,7 @@ namespace RebootReality.jelycho.Player {
|
||||
//
|
||||
// @MARK: Sensors
|
||||
//
|
||||
bool TryGetBeaconPosition(out Vector3 position) {
|
||||
public bool TryGetBeaconPosition(out Vector3 position) {
|
||||
Ray ray = new Ray(m_Camera.Camera.transform.position, m_Camera.Camera.transform.forward);
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, m_BeaconPlacementMaxDistance, m_BeaconPlacementLayerMask) &&
|
||||
Vector3.Dot(hit.normal, Vector3.up) >= m_NormalDotUpThreshold) {
|
||||
@@ -721,6 +812,10 @@ namespace RebootReality.jelycho.Player {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Vector3 GetAttackPosition() {
|
||||
return m_Camera.transform.position + m_Camera.transform.forward * 1.5f;
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Inventory
|
||||
//
|
||||
@@ -797,12 +892,6 @@ namespace RebootReality.jelycho.Player {
|
||||
public static readonly int VelocityRightNormalized = Animator.StringToHash("VelocityRightNormalized");
|
||||
public static readonly int TurnVelocity = Animator.StringToHash("TurnVelocity");
|
||||
public static readonly int IsGrounded = Animator.StringToHash("IsGrounded");
|
||||
|
||||
public static readonly int Attack = Animator.StringToHash("Attack");
|
||||
public static readonly int Block = Animator.StringToHash("Block");
|
||||
public static readonly int Throw = Animator.StringToHash("Throw");
|
||||
|
||||
public static readonly int Holding = Animator.StringToHash("Holding");
|
||||
}
|
||||
|
||||
void UpdateAnimator(Vector3 velocity) {
|
||||
@@ -822,7 +911,6 @@ namespace RebootReality.jelycho.Player {
|
||||
m_Animator.SetFloat(AnimatorParamHashes.TurnVelocity, turnVelocity);
|
||||
|
||||
m_Animator.SetBool(AnimatorParamHashes.IsGrounded, m_Locomotion.IsGrounded);
|
||||
m_Animator.SetInteger(AnimatorParamHashes.Holding, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,6 +963,8 @@ namespace RebootReality.jelycho.Player {
|
||||
DropItem = 0x03,
|
||||
EquipItem = 0x04,
|
||||
SelectItemSlot = 0x05,
|
||||
RequestHandsAnimation = 0x06,
|
||||
DealDamage = 0x07
|
||||
}
|
||||
|
||||
struct PlayerActorPickupItemCommand : IActorData {
|
||||
@@ -940,6 +1030,38 @@ namespace RebootReality.jelycho.Player {
|
||||
return sizeof(int); // SlotIndex
|
||||
}
|
||||
}
|
||||
|
||||
struct PlayerActorRequestHandsAnimationCommand : IActorData {
|
||||
public int AnimationHash;
|
||||
|
||||
public void Serialize(NetworkBufferWriter writer) {
|
||||
writer.Write(AnimationHash);
|
||||
}
|
||||
|
||||
public void Deserialize(NetworkBufferReader reader) {
|
||||
reader.Read(out AnimationHash);
|
||||
}
|
||||
|
||||
public int GetMaxBytes() {
|
||||
return sizeof(int);
|
||||
}
|
||||
}
|
||||
|
||||
struct PlayerActorDealDamageCommand : IActorData {
|
||||
public ushort TargetActorID;
|
||||
|
||||
public int GetMaxBytes() {
|
||||
return sizeof(ushort);
|
||||
}
|
||||
|
||||
public void Serialize(NetworkBufferWriter writer) {
|
||||
writer.Write(TargetActorID);
|
||||
}
|
||||
|
||||
public void Deserialize(NetworkBufferReader reader) {
|
||||
reader.Read(out TargetActorID);
|
||||
}
|
||||
}
|
||||
|
||||
// @MARK: Player Actor Events
|
||||
enum PlayerActorEvents : byte {
|
||||
@@ -947,6 +1069,7 @@ namespace RebootReality.jelycho.Player {
|
||||
PrimaryEquippedItemChanged = 0x01,
|
||||
UpdatedRemoteState = 0x02,
|
||||
UpdateInventory = 0x03,
|
||||
PlayHandsAnimation = 0x04,
|
||||
}
|
||||
|
||||
struct PlayerActorPrimaryEquippedItemChangedEvent : IActorData {
|
||||
@@ -988,4 +1111,20 @@ namespace RebootReality.jelycho.Player {
|
||||
return sizeof(byte) + SlotsActorIDs.Length * sizeof(ushort);
|
||||
}
|
||||
}
|
||||
|
||||
struct PlayerPlayHandsAnimationEvent : IActorData {
|
||||
public int AnimationHash;
|
||||
|
||||
public void Serialize(NetworkBufferWriter writer) {
|
||||
writer.Write(AnimationHash);
|
||||
}
|
||||
|
||||
public void Deserialize(NetworkBufferReader reader) {
|
||||
reader.Read(out AnimationHash);
|
||||
}
|
||||
|
||||
public int GetMaxBytes() {
|
||||
return sizeof(int);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,14 +116,6 @@ namespace RebootReality.jelycho.Player {
|
||||
m_Actor.Jump();
|
||||
}
|
||||
|
||||
if (m_Config.dragObjectActionReference.action.WasPressedThisFrame()) {
|
||||
m_Actor.StartDrag();
|
||||
}
|
||||
|
||||
if (m_Config.dragObjectActionReference.action.WasReleasedThisFrame()) {
|
||||
m_Actor.StopDrag();
|
||||
}
|
||||
|
||||
if (m_Config.dropItemActionReference.action.WasReleasedThisFrame()) {
|
||||
m_Actor.DropItem();
|
||||
}
|
||||
@@ -132,6 +124,10 @@ namespace RebootReality.jelycho.Player {
|
||||
m_Actor.BeginPrimaryAction();
|
||||
}
|
||||
|
||||
if (m_Config.primaryActionReference.action.IsPressed()) {
|
||||
m_Actor.HoldingPrimaryAction();
|
||||
}
|
||||
|
||||
if (m_Config.primaryActionReference.action.WasReleasedThisFrame()) {
|
||||
m_Actor.EndPrimaryAction();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using RebootKit.Engine.Simulation;
|
||||
using RebootReality.jelycho.Beacons;
|
||||
using RebootReality.jelycho.Feedbacks;
|
||||
using RebootReality.jelycho.Ropes;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -8,5 +9,6 @@ namespace RebootReality.jelycho {
|
||||
[field: SerializeField] public Transform PlayerSpawnPoint { get; private set; }
|
||||
[field: SerializeField] public RopesManager RopesManager { get; private set; }
|
||||
[field: SerializeField] public BaseManagerActor BaseManager { get; private set; }
|
||||
[field: SerializeField] public FeedbacksManagerActor FeedbacksManager { get; private set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user