2024-01-26 16:26:50 +00:00
|
|
|
using System;
|
2024-02-12 20:50:24 +00:00
|
|
|
using System.Collections;
|
2024-01-26 16:26:50 +00:00
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.InputSystem;
|
|
|
|
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
|
|
namespace BlueWaterProject
|
|
|
|
{
|
2024-02-16 08:12:48 +00:00
|
|
|
public class PhysicsMovement : MonoBehaviour, IStun
|
2024-01-26 16:26:50 +00:00
|
|
|
{
|
|
|
|
/***********************************************************************
|
|
|
|
* Definitions
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
#region Class
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class Components
|
|
|
|
{
|
|
|
|
public CapsuleCollider capsuleCollider;
|
|
|
|
public Rigidbody rb;
|
|
|
|
[ShowIf("@false")]
|
|
|
|
public Animator animator;
|
2024-01-30 02:49:41 +00:00
|
|
|
public Transform[] spawnPosition;
|
2024-01-26 16:26:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class CheckOption
|
|
|
|
{
|
|
|
|
[Tooltip("지면으로 체크할 레이어 설정")]
|
|
|
|
public LayerMask groundLayer = -1;
|
|
|
|
|
|
|
|
[Range(0.01f, 0.5f), Tooltip("전방 감지 거리")]
|
|
|
|
public float forwardCheckDistance = 0.1f;
|
|
|
|
|
|
|
|
[Range(0.1f, 10.0f), Tooltip("지면 감지 거리")]
|
|
|
|
public float groundCheckDistance = 2.0f;
|
|
|
|
|
|
|
|
[Range(0.0f, 0.5f), Tooltip("지면 인식 허용 거리")]
|
|
|
|
public float groundCheckThreshold = 0.01f;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class MovementOption
|
|
|
|
{
|
|
|
|
[Range(1f, 10f), Tooltip("이동 속도")]
|
|
|
|
public float moveSpeed = 10f;
|
|
|
|
|
|
|
|
[Range(1f, 75f), Tooltip("등반 가능한 경사각")]
|
|
|
|
public float maxSlopeAngle = 50f;
|
|
|
|
|
|
|
|
[Range(1f, 50f), Tooltip("대쉬 속도")]
|
|
|
|
public float dashSpeed = 30f;
|
|
|
|
|
|
|
|
[Range(0.1f, 1f), Tooltip("대쉬 시간")]
|
|
|
|
public float dashTime = 0.2f;
|
|
|
|
|
|
|
|
[Range(0f, 5f), Tooltip("대쉬 쿨타임")]
|
|
|
|
public float dashCooldown = 0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
[DisableIf("@true")]
|
|
|
|
public class CurrentState
|
|
|
|
{
|
2024-01-28 15:46:56 +00:00
|
|
|
public bool enableMoving = true;
|
2024-01-26 16:26:50 +00:00
|
|
|
public bool isMoving;
|
|
|
|
public bool isGrounded;
|
|
|
|
public bool isOnSlope;
|
|
|
|
public bool isOnSteepSlope;
|
|
|
|
public bool isForwardBlocked;
|
|
|
|
public bool isOutOfControl;
|
|
|
|
public bool isDashing;
|
|
|
|
public bool enableDash = true;
|
2024-02-16 08:12:48 +00:00
|
|
|
public bool isStunned;
|
2024-01-26 16:26:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
[DisableIf("@true")]
|
|
|
|
public class CurrentValue
|
|
|
|
{
|
|
|
|
public Vector2 movementInput;
|
|
|
|
public Vector3 currentMoveDirection;
|
|
|
|
public Vector3 previousMoveDirection = Vector3.back;
|
|
|
|
public Vector3 groundNormal;
|
|
|
|
public Vector3 groundCross;
|
|
|
|
public Vector3 horizontalVelocity;
|
|
|
|
|
|
|
|
[Space]
|
|
|
|
public float outOfControlDuration;
|
|
|
|
|
|
|
|
[Space]
|
|
|
|
public float groundDistance;
|
|
|
|
public float groundSlopeAngle; // 현재 바닥의 경사각
|
|
|
|
public float forwardSlopeAngle; // 캐릭터가 바라보는 방향의 경사각
|
|
|
|
|
|
|
|
[Space]
|
|
|
|
public Vector3 gravity;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Variables
|
|
|
|
***********************************************************************/
|
|
|
|
#region Variables
|
|
|
|
|
|
|
|
[field: SerializeField] public Components MyComponents { get; private set; } = new();
|
|
|
|
[field: SerializeField] public CheckOption MyCheckOption { get; private set; } = new();
|
|
|
|
[field: SerializeField] public MovementOption MyMovementOption { get; private set; } = new();
|
|
|
|
[field: SerializeField] public CurrentState MyCurrentState { get; set; } = new();
|
|
|
|
[field: SerializeField] public CurrentValue MyCurrentValue { get; set; } = new();
|
2024-02-16 08:12:48 +00:00
|
|
|
|
|
|
|
[Title("효과")]
|
|
|
|
[SerializeField] private ParticleSystem stunParticle;
|
2024-01-26 16:26:50 +00:00
|
|
|
|
2024-02-16 08:12:48 +00:00
|
|
|
public bool IsStunned
|
|
|
|
{
|
|
|
|
get => MyCurrentState.isStunned;
|
|
|
|
set => MyCurrentState.isStunned = value;
|
|
|
|
}
|
2024-01-26 16:26:50 +00:00
|
|
|
private float capsuleRadiusDifferent;
|
|
|
|
private float castRadius;
|
|
|
|
|
|
|
|
private Vector3 CapsuleTopCenterPoint => new(transform.position.x,
|
|
|
|
transform.position.y + MyComponents.capsuleCollider.height - MyComponents.capsuleCollider.radius,
|
|
|
|
transform.position.z);
|
|
|
|
|
|
|
|
private Vector3 CapsuleBottomCenterPoint => new(transform.position.x,
|
|
|
|
transform.position.y + MyComponents.capsuleCollider.radius,
|
|
|
|
transform.position.z);
|
|
|
|
|
|
|
|
public static readonly int IsDashingHash = Animator.StringToHash("isDashing");
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Unity Events
|
|
|
|
***********************************************************************/
|
|
|
|
#region Unity Events
|
|
|
|
|
|
|
|
private void Start()
|
|
|
|
{
|
|
|
|
InitRigidbody();
|
|
|
|
InitCapsuleCollider();
|
|
|
|
InitStartValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void FixedUpdate()
|
|
|
|
{
|
2024-02-16 08:12:48 +00:00
|
|
|
if (!MyCurrentState.enableMoving || IsStunned) return;
|
2024-01-28 15:46:56 +00:00
|
|
|
|
2024-01-26 16:26:50 +00:00
|
|
|
InputMove();
|
|
|
|
CheckGround();
|
|
|
|
CheckForward();
|
|
|
|
|
|
|
|
UpdateValues();
|
|
|
|
|
|
|
|
CalculateMovements();
|
|
|
|
ApplyMovementsToRigidbody();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Init Methods
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
#region Init Methods
|
|
|
|
|
|
|
|
private void InitRigidbody()
|
|
|
|
{
|
|
|
|
if (TryGetComponent(out MyComponents.rb)) return;
|
|
|
|
|
|
|
|
MyComponents.rb = gameObject.AddComponent<Rigidbody>();
|
|
|
|
MyComponents.rb.constraints = RigidbodyConstraints.FreezeRotation;
|
|
|
|
MyComponents.rb.interpolation = RigidbodyInterpolation.Interpolate;
|
|
|
|
MyComponents.rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
|
|
|
MyComponents.rb.useGravity = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void InitCapsuleCollider()
|
|
|
|
{
|
|
|
|
if (!TryGetComponent(out MyComponents.capsuleCollider))
|
|
|
|
{
|
|
|
|
MyComponents.capsuleCollider = gameObject.AddComponent<CapsuleCollider>();
|
|
|
|
|
|
|
|
MyComponents.capsuleCollider.height = 2f;
|
|
|
|
MyComponents.capsuleCollider.center = Vector3.up;
|
|
|
|
MyComponents.capsuleCollider.radius = 0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
var capsuleColliderRadius = MyComponents.capsuleCollider.radius;
|
|
|
|
castRadius = capsuleColliderRadius * 0.9f;
|
|
|
|
capsuleRadiusDifferent = capsuleColliderRadius - castRadius + 0.05f;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void InitStartValue()
|
|
|
|
{
|
|
|
|
MyCurrentValue.gravity = Physics.gravity;
|
2024-02-16 08:12:48 +00:00
|
|
|
if (stunParticle)
|
|
|
|
{
|
|
|
|
stunParticle.Stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Interfaces
|
|
|
|
***********************************************************************/
|
|
|
|
#region Interfaces
|
|
|
|
|
|
|
|
public void Stun(float stunTime)
|
|
|
|
{
|
|
|
|
if (MyCurrentState.isDashing) return;
|
|
|
|
|
|
|
|
IsStunned = true;
|
|
|
|
|
|
|
|
if (stunParticle)
|
|
|
|
{
|
|
|
|
stunParticle.Play();
|
|
|
|
}
|
|
|
|
|
|
|
|
StartCoroutine(Utils.CoolDown(stunTime, StopStun));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void StopStun()
|
|
|
|
{
|
|
|
|
if (stunParticle)
|
|
|
|
{
|
|
|
|
stunParticle.Stop();
|
|
|
|
}
|
|
|
|
IsStunned = false;
|
2024-01-26 16:26:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* PlayerInput
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
#region PlayerInput
|
|
|
|
|
|
|
|
private void OnMove(InputValue value)
|
|
|
|
{
|
|
|
|
MyCurrentValue.movementInput = value.Get<Vector2>();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnDash()
|
|
|
|
{
|
|
|
|
if (!MyCurrentState.enableDash || MyCurrentState.isDashing) return;
|
|
|
|
|
|
|
|
MyComponents.animator.SetBool(IsDashingHash, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Methods
|
|
|
|
***********************************************************************/
|
|
|
|
#region Methods
|
|
|
|
|
|
|
|
private void InputMove()
|
|
|
|
{
|
|
|
|
if (MyCurrentValue.currentMoveDirection != Vector3.zero)
|
|
|
|
{
|
|
|
|
MyCurrentValue.previousMoveDirection = MyCurrentValue.currentMoveDirection;
|
|
|
|
}
|
|
|
|
MyCurrentValue.currentMoveDirection = MyCurrentState.isDashing
|
|
|
|
? MyCurrentValue.previousMoveDirection
|
|
|
|
: new Vector3(MyCurrentValue.movementInput.x, 0,MyCurrentValue.movementInput.y).normalized;
|
|
|
|
MyCurrentState.isMoving = MyCurrentValue.currentMoveDirection != Vector3.zero;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> 하단 지면 검사 </summary>
|
|
|
|
private void CheckGround()
|
|
|
|
{
|
|
|
|
MyCurrentValue.groundDistance = float.MaxValue;
|
|
|
|
MyCurrentValue.groundNormal = Vector3.up;
|
|
|
|
MyCurrentValue.groundSlopeAngle = 0f;
|
|
|
|
MyCurrentValue.forwardSlopeAngle = 0f;
|
|
|
|
|
|
|
|
var groundRaycast = Physics.SphereCast(CapsuleBottomCenterPoint, castRadius,Vector3.down,
|
|
|
|
out var hit, MyCheckOption.groundCheckDistance, MyCheckOption.groundLayer, QueryTriggerInteraction.Ignore);
|
|
|
|
|
|
|
|
MyCurrentState.isGrounded = false;
|
|
|
|
|
|
|
|
if (groundRaycast)
|
|
|
|
{
|
|
|
|
MyCurrentValue.groundNormal = hit.normal;
|
|
|
|
MyCurrentValue.groundSlopeAngle = Vector3.Angle(MyCurrentValue.groundNormal, Vector3.up);
|
|
|
|
MyCurrentValue.forwardSlopeAngle = Vector3.Angle(MyCurrentValue.groundNormal, MyCurrentValue.currentMoveDirection) - 90f;
|
|
|
|
MyCurrentState.isOnSlope = MyCurrentValue.groundSlopeAngle > 0f && MyCurrentValue.groundSlopeAngle < MyMovementOption.maxSlopeAngle;
|
|
|
|
MyCurrentState.isOnSteepSlope = MyCurrentValue.groundSlopeAngle >= MyMovementOption.maxSlopeAngle;
|
|
|
|
|
|
|
|
// 경사각 이중검증 (수직 레이캐스트) : 뾰족하거나 각진 부분 체크
|
|
|
|
//if (State.isOnSteepSlope)
|
|
|
|
//{
|
|
|
|
// Vector3 ro = hit.point + Vector3.up * 0.1f;
|
|
|
|
// Vector3 rd = Vector3.down;
|
|
|
|
// bool rayD =
|
|
|
|
// Physics.SphereCast(ro, 0.09f, rd, out var hitRayD, 0.2f, COption.groundLayerMask, QueryTriggerInteraction.Ignore);
|
|
|
|
|
|
|
|
// Current.groundVerticalSlopeAngle = rayD ? Vector3.Angle(hitRayD.normal, Vector3.up) : Current.groundSlopeAngle;
|
|
|
|
|
|
|
|
// State.isOnSteepSlope = Current.groundVerticalSlopeAngle >= MOption.maxSlopeAngle;
|
|
|
|
//}
|
|
|
|
|
|
|
|
MyCurrentValue.groundDistance = Mathf.Max(hit.distance - capsuleRadiusDifferent - MyCheckOption.groundCheckThreshold, 0f);
|
|
|
|
MyCurrentState.isGrounded = (MyCurrentValue.groundDistance <= 0.0001f) && !MyCurrentState.isOnSteepSlope;
|
|
|
|
|
|
|
|
GizmosUpdateValue(ref gzGroundTouch, hit.point);
|
|
|
|
}
|
|
|
|
|
|
|
|
MyCurrentValue.groundCross = Vector3.Cross(MyCurrentValue.groundNormal, Vector3.up);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> 전방 장애물 검사 : 레이어 관계 없이 trigger가 아닌 모든 장애물 검사 </summary>
|
|
|
|
private void CheckForward()
|
|
|
|
{
|
|
|
|
var obstacleRaycast = Physics.CapsuleCast(CapsuleBottomCenterPoint, CapsuleTopCenterPoint, castRadius,
|
|
|
|
MyCurrentValue.currentMoveDirection + Vector3.down * 0.1f,
|
|
|
|
out var hit, MyCheckOption.forwardCheckDistance, -1, QueryTriggerInteraction.Ignore);
|
|
|
|
|
|
|
|
MyCurrentState.isForwardBlocked = false;
|
|
|
|
if (obstacleRaycast)
|
|
|
|
{
|
|
|
|
var forwardObstacleAngle = Vector3.Angle(hit.normal, Vector3.up);
|
|
|
|
MyCurrentState.isForwardBlocked = forwardObstacleAngle >= MyMovementOption.maxSlopeAngle;
|
|
|
|
|
|
|
|
GizmosUpdateValue(ref gzForwardTouch, hit.point);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UpdateValues()
|
|
|
|
{
|
|
|
|
MyCurrentState.isOutOfControl = MyCurrentValue.outOfControlDuration > 0f;
|
|
|
|
|
|
|
|
if (MyCurrentState.isOutOfControl)
|
|
|
|
{
|
|
|
|
MyCurrentValue.outOfControlDuration -= Time.fixedDeltaTime;
|
|
|
|
MyCurrentValue.currentMoveDirection = Vector3.zero;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void CalculateMovements()
|
|
|
|
{
|
|
|
|
if (MyCurrentState.isOutOfControl)
|
|
|
|
{
|
|
|
|
MyComponents.rb.useGravity = true;
|
|
|
|
MyCurrentValue.horizontalVelocity = Vector3.zero;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var speed = 0f;
|
|
|
|
if (MyCurrentState.isDashing)
|
|
|
|
{
|
|
|
|
speed = MyMovementOption.dashSpeed;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
speed = MyCurrentState.isMoving ? MyMovementOption.moveSpeed : 0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MyCurrentState.isOnSlope)
|
|
|
|
{
|
|
|
|
MyComponents.rb.useGravity = false;
|
|
|
|
|
|
|
|
if (MyCurrentState.isMoving)
|
|
|
|
{
|
|
|
|
var changeMoveDirection = Vector3.ProjectOnPlane(MyCurrentValue.currentMoveDirection, MyCurrentValue.groundNormal).normalized;
|
|
|
|
MyCurrentValue.horizontalVelocity = changeMoveDirection * speed;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MyCurrentValue.horizontalVelocity = Vector3.zero;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MyComponents.rb.useGravity = true;
|
|
|
|
if (MyCurrentState.isForwardBlocked || !MyCurrentState.isGrounded)
|
|
|
|
{
|
|
|
|
MyCurrentValue.horizontalVelocity = Vector3.zero;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MyCurrentValue.horizontalVelocity = MyCurrentValue.currentMoveDirection * speed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> 리지드바디 최종 속도 적용 </summary>
|
|
|
|
private void ApplyMovementsToRigidbody()
|
|
|
|
{
|
|
|
|
Vector3 finalVelocity;
|
|
|
|
if (MyCurrentState.isOutOfControl || MyCurrentState.isOnSteepSlope || !MyCurrentState.isGrounded)
|
|
|
|
{
|
2024-02-12 20:50:24 +00:00
|
|
|
// var velocity = MyComponents.rb.velocity;
|
|
|
|
// finalVelocity = MyComponents.rb.position + new Vector3(velocity.x, MyCurrentValue.gravity.y, velocity.z) * Time.fixedDeltaTime;
|
|
|
|
// MyComponents.rb.MovePosition(finalVelocity);
|
2024-01-26 16:26:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (MyCurrentValue.horizontalVelocity == Vector3.zero)
|
|
|
|
{
|
|
|
|
MyComponents.rb.velocity = Vector3.zero;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
finalVelocity = MyComponents.rb.position + MyCurrentValue.horizontalVelocity * Time.fixedDeltaTime;
|
|
|
|
MyComponents.rb.MovePosition(finalVelocity);
|
2024-02-12 20:50:24 +00:00
|
|
|
|
|
|
|
// finalVelocity = MyCurrentValue.horizontalVelocity;
|
|
|
|
// MyComponents.rb.velocity = finalVelocity;
|
2024-01-26 16:26:50 +00:00
|
|
|
}
|
2024-02-12 20:50:24 +00:00
|
|
|
|
|
|
|
public void Move(Vector3 position) => MyComponents.rb.position = position;
|
2024-01-26 16:26:50 +00:00
|
|
|
|
2024-02-12 20:50:24 +00:00
|
|
|
public void SpawnPlayer(Vector3 position)
|
2024-01-28 15:46:56 +00:00
|
|
|
{
|
2024-02-12 20:50:24 +00:00
|
|
|
Move(position);
|
|
|
|
|
|
|
|
var bossPortal = GameObject.Find("DesertBossArea").transform.Find("BossPortal").GetComponent<BossPortal>();
|
|
|
|
if (bossPortal)
|
|
|
|
{
|
|
|
|
bossPortal.ResetPortal();
|
|
|
|
}
|
2024-01-28 15:46:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void MoveToCurrentDirection(float speed)
|
|
|
|
{
|
2024-02-16 08:12:48 +00:00
|
|
|
var finalVelocity = MyComponents.rb.position + MyCurrentValue.previousMoveDirection * (speed * Time.fixedDeltaTime);
|
2024-01-28 15:46:56 +00:00
|
|
|
MyComponents.rb.MovePosition(finalVelocity);
|
2024-02-12 20:50:24 +00:00
|
|
|
|
|
|
|
// var finalVelocity = MyCurrentValue.previousMoveDirection * speed;
|
|
|
|
// MyComponents.rb.velocity = finalVelocity;
|
2024-01-28 15:46:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void SetEnableMoving(bool value) => MyCurrentState.enableMoving = value;
|
2024-01-26 16:26:50 +00:00
|
|
|
public bool GetIsMoving() => MyCurrentState.isMoving;
|
|
|
|
public bool GetIsDashing() => MyCurrentState.isDashing;
|
|
|
|
public float GetDashCooldown() => MyMovementOption.dashCooldown;
|
|
|
|
public float GetDashTime() => MyMovementOption.dashTime;
|
|
|
|
public void SetIsDashing(bool value) => MyCurrentState.isDashing = value;
|
|
|
|
public void SetEnableDashing(bool value) => MyCurrentState.enableDash = value;
|
|
|
|
public Vector3 GetPreviousMoveDirection() => MyCurrentValue.previousMoveDirection;
|
2024-01-28 15:46:56 +00:00
|
|
|
public void SetPreviousMoveDirection(Vector3 value) => MyCurrentValue.previousMoveDirection = value;
|
2024-01-26 16:26:50 +00:00
|
|
|
public void SetAnimator(Animator animator) => MyComponents.animator = animator;
|
2024-01-28 15:46:56 +00:00
|
|
|
public Vector3 GetCurrentPosition() => MyComponents.rb.position;
|
|
|
|
public void SetIsTrigger(bool value) => MyComponents.capsuleCollider.isTrigger = value;
|
|
|
|
public void SetUseGravity(bool value) => MyComponents.rb.useGravity = value;
|
2024-01-26 16:26:50 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* Gizmos, GUI
|
|
|
|
***********************************************************************/
|
|
|
|
#region Gizmos, GUI
|
|
|
|
|
|
|
|
private Vector3 gzGroundTouch;
|
|
|
|
private Vector3 gzForwardTouch;
|
|
|
|
|
|
|
|
[Header("Gizmos Option")] public bool showGizmos = true;
|
|
|
|
|
|
|
|
[SerializeField, Range(0.01f, 2f)] private float gizmoRadius = 0.05f;
|
|
|
|
|
|
|
|
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
|
|
|
private void OnDrawGizmos()
|
|
|
|
{
|
|
|
|
if (Application.isPlaying == false) return;
|
|
|
|
if (!showGizmos) return;
|
|
|
|
if (!enabled) return;
|
|
|
|
|
|
|
|
Gizmos.color = Color.red;
|
|
|
|
Gizmos.DrawSphere(gzGroundTouch, gizmoRadius);
|
|
|
|
|
|
|
|
if (MyCurrentState.isForwardBlocked)
|
|
|
|
{
|
|
|
|
Gizmos.color = Color.blue;
|
|
|
|
Gizmos.DrawSphere(gzForwardTouch, gizmoRadius);
|
|
|
|
}
|
|
|
|
|
|
|
|
Gizmos.color = Color.blue;
|
|
|
|
Gizmos.DrawLine(gzGroundTouch - MyCurrentValue.groundCross,
|
|
|
|
gzGroundTouch + MyCurrentValue.groundCross);
|
|
|
|
|
|
|
|
Gizmos.color = new Color(0.5f, 1.0f, 0.8f, 0.8f);
|
|
|
|
Gizmos.DrawWireSphere(CapsuleTopCenterPoint, castRadius);
|
|
|
|
Gizmos.DrawWireSphere(CapsuleBottomCenterPoint, castRadius);
|
|
|
|
}
|
|
|
|
|
|
|
|
[System.Diagnostics.Conditional("UNITY_EDITOR")]
|
|
|
|
private void GizmosUpdateValue<T>(ref T variable, in T value)
|
|
|
|
{
|
|
|
|
variable = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
[SerializeField, Space] private bool showGUI = true;
|
|
|
|
[SerializeField] private int guiTextSize = 28;
|
|
|
|
|
|
|
|
private float prevForwardSlopeAngle;
|
|
|
|
|
|
|
|
private void OnGUI()
|
|
|
|
{
|
|
|
|
if (Application.isPlaying == false) return;
|
|
|
|
if (!showGUI) return;
|
|
|
|
if (!enabled) return;
|
|
|
|
|
|
|
|
GUIStyle labelStyle = GUI.skin.label;
|
|
|
|
labelStyle.normal.textColor = Color.yellow;
|
|
|
|
labelStyle.fontSize = Math.Max(guiTextSize, 20);
|
|
|
|
|
|
|
|
prevForwardSlopeAngle = MyCurrentValue.forwardSlopeAngle == -90f
|
|
|
|
? prevForwardSlopeAngle
|
|
|
|
: MyCurrentValue.forwardSlopeAngle;
|
|
|
|
|
|
|
|
var oldColor = GUI.color;
|
|
|
|
GUI.color = new Color(0f, 0f, 0f, 0.5f);
|
|
|
|
GUI.Box(new Rect(40, 40, 420, 240), "");
|
|
|
|
GUI.color = oldColor;
|
|
|
|
|
|
|
|
GUILayout.BeginArea(new Rect(50, 50, 1000, 500));
|
|
|
|
GUILayout.Label($"Ground Height : {Mathf.Min(MyCurrentValue.groundDistance, 99.99f): 00.00}",
|
|
|
|
labelStyle);
|
|
|
|
GUILayout.Label($"Slope Angle(Ground) : {MyCurrentValue.groundSlopeAngle: 00.00}", labelStyle);
|
|
|
|
GUILayout.Label($"Slope Angle(Forward) : {prevForwardSlopeAngle: 00.00}", labelStyle);
|
|
|
|
GUILayout.Label($"Allowed Slope Angle : {MyMovementOption.maxSlopeAngle: 00.00}", labelStyle);
|
|
|
|
GUILayout.Label($"Current Speed Mag : {MyCurrentValue.horizontalVelocity.magnitude: 00.00}",
|
|
|
|
labelStyle);
|
|
|
|
GUILayout.EndArea();
|
|
|
|
|
|
|
|
float sWidth = Screen.width;
|
|
|
|
float sHeight = Screen.height;
|
|
|
|
|
|
|
|
GUIStyle RTLabelStyle = GUI.skin.label;
|
|
|
|
RTLabelStyle.fontSize = 20;
|
|
|
|
RTLabelStyle.normal.textColor = Color.green;
|
|
|
|
|
|
|
|
oldColor = GUI.color;
|
|
|
|
GUI.color = new Color(1f, 1f, 1f, 0.5f);
|
|
|
|
GUI.Box(new Rect(sWidth - 355f, 5f, 340f, 100f), "");
|
|
|
|
GUI.color = oldColor;
|
|
|
|
|
|
|
|
var yPos = 10f;
|
|
|
|
GUI.Label(new Rect(sWidth - 350f, yPos, 150f, 30f), $"Speed : {MyMovementOption.moveSpeed: 00.00}",
|
|
|
|
RTLabelStyle);
|
2024-01-28 15:46:56 +00:00
|
|
|
MyMovementOption.moveSpeed = GUI.HorizontalSlider(new Rect(sWidth - 180f, yPos + 10f, 160f, 20f),
|
2024-01-26 16:26:50 +00:00
|
|
|
MyMovementOption.moveSpeed, 1f, 10f);
|
|
|
|
|
|
|
|
yPos += 20f;
|
|
|
|
GUI.Label(new Rect(sWidth - 350f, yPos, 150f, 30f), $"Max Slope : {MyMovementOption.maxSlopeAngle: 00}",
|
|
|
|
RTLabelStyle);
|
|
|
|
MyMovementOption.maxSlopeAngle = (int)GUI.HorizontalSlider(
|
2024-01-28 15:46:56 +00:00
|
|
|
new Rect(sWidth - 180f, yPos + 10f, 160f, 20f), MyMovementOption.maxSlopeAngle, 1f, 75f);
|
|
|
|
|
|
|
|
yPos += 20f;
|
|
|
|
GUI.Label(new Rect(sWidth - 350f, yPos, 180f, 30f), $"TimeScale : {Time.timeScale: 0.00}",
|
|
|
|
RTLabelStyle);
|
|
|
|
Time.timeScale = GUI.HorizontalSlider(
|
|
|
|
new Rect(sWidth - 180f, yPos + 10f, 160f, 20f), Time.timeScale, 0f, 1f);
|
|
|
|
Time.fixedDeltaTime = 0.02f * Time.timeScale;
|
2024-01-30 02:49:41 +00:00
|
|
|
|
|
|
|
yPos = 130f;
|
|
|
|
var buttonWidth = 200f;
|
|
|
|
var buttonHeight = 30f;
|
|
|
|
var buttonSpacing = 35f;
|
|
|
|
|
|
|
|
var buttonStyle = GUI.skin.button;
|
|
|
|
buttonStyle.fontSize = 15;
|
|
|
|
|
|
|
|
var spawnPosition = MyComponents.spawnPosition;
|
|
|
|
for (var i = 0; i < spawnPosition.Length; i++)
|
|
|
|
{
|
|
|
|
if (GUI.Button(new Rect(sWidth - 350f, yPos, buttonWidth, buttonHeight), spawnPosition[i].name, buttonStyle))
|
|
|
|
{
|
2024-02-12 20:50:24 +00:00
|
|
|
SpawnPlayer(spawnPosition[i].position);
|
2024-01-30 02:49:41 +00:00
|
|
|
}
|
|
|
|
yPos += buttonSpacing;
|
|
|
|
}
|
2024-01-26 16:26:50 +00:00
|
|
|
|
|
|
|
labelStyle.fontSize = Math.Max(guiTextSize, 20);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|