289 lines
6.6 KiB
C#
289 lines
6.6 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
|
|
public class MovePlayer : CoreBehaviour
|
|
{
|
|
public class XpositionWanted
|
|
{
|
|
public float xRef;
|
|
|
|
public float xOffset;
|
|
}
|
|
|
|
public Rigidbody body;
|
|
|
|
public SwerveXInputHandler swerveInput;
|
|
|
|
public SwerveXSmoothMover swerveSmoothMove;
|
|
|
|
public GameObject toMove;
|
|
|
|
public GameObject umbrella;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("turnZoneHandler")]
|
|
private TurnZoneHandler _turnZoneHandler;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("visualRotation")]
|
|
private GameObject _visualRotation;
|
|
|
|
private float _lastPosY;
|
|
|
|
private float _speed;
|
|
|
|
private Player player;
|
|
|
|
private bool _isTurn;
|
|
|
|
private Section _curSectionTurn;
|
|
|
|
private float _curStartYTurn;
|
|
|
|
private float speedRatio = 1f;
|
|
private float _desiredRotVisual;
|
|
|
|
private float _needWaitToMove;
|
|
|
|
private int LayerGround;
|
|
|
|
private float _prevSetX;
|
|
|
|
private XpositionWanted _xPositionWanted;
|
|
|
|
private Vector3 _targetPos;
|
|
|
|
private Vector3 _oldPosition;
|
|
|
|
public float smoothTimeY;
|
|
|
|
public float maxSpeedY;
|
|
|
|
private float _currentYSpeed;
|
|
|
|
public float curSpeed { get; private set; }
|
|
|
|
public bool verti { get; private set; } = true;
|
|
|
|
public float speed
|
|
{
|
|
get
|
|
{
|
|
return _speed;
|
|
}
|
|
private set
|
|
{
|
|
_speed = value;
|
|
player.anim.SetFloat("Speed", value);
|
|
}
|
|
}
|
|
|
|
public void Setup(Player p)
|
|
{
|
|
LayerGround = LayerMask.GetMask("Ground");
|
|
player = p;
|
|
SetUmbrellaParent(base.transform, (Transform t) => t.name == "mixamorig:RightHand");
|
|
ActiveUmbrella(active: false);
|
|
swerveInput.trackWidth = base.CoreDef.levelWidth;
|
|
swerveSmoothMove.maxSpeed = base.CoreDef.player.lateralMaxSpeed;
|
|
swerveSmoothMove.smoothTime = base.CoreDef.player.lateralSmoothTime;
|
|
maxSpeedY = base.CoreDef.player.heightMaxSpeed;
|
|
smoothTimeY = base.CoreDef.player.heightSmoothTime;
|
|
_desiredRotVisual = _visualRotation.transform.localEulerAngles.y;
|
|
_lastPosY = 0f;
|
|
_turnZoneHandler.onTurn += OnTurn;
|
|
}
|
|
|
|
private Transform SetUmbrellaParent(Transform parent, Func<Transform, bool> query)
|
|
{
|
|
Transform found = null;
|
|
if (parent.childCount > 0)
|
|
{
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
Transform child = parent.GetChild(i);
|
|
if (query(child))
|
|
{
|
|
Vector3 localPosition = umbrella.transform.localPosition;
|
|
Vector3 localEulerAngles = umbrella.transform.localEulerAngles;
|
|
umbrella.transform.SetParent(child);
|
|
umbrella.transform.localPosition = localPosition;
|
|
umbrella.transform.localEulerAngles = localEulerAngles;
|
|
return child;
|
|
}
|
|
found = SetUmbrellaParent(child, query);
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
private void ActiveUmbrella(bool active)
|
|
{
|
|
umbrella.SetActive(active);
|
|
player.anim.SetBool("Flying", active);
|
|
}
|
|
|
|
public void Go()
|
|
{
|
|
curSpeed = base.CoreDef.player.RunningSpeed;
|
|
swerveInput.activeControl(active: true);
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (player.Win)
|
|
{
|
|
RotateWin();
|
|
speed = 0f;
|
|
return;
|
|
}
|
|
if (!player.Started || player.isDie)
|
|
{
|
|
speed = 0f;
|
|
return;
|
|
}
|
|
speed = Vector3.Distance(_oldPosition, toMove.transform.position) / Time.deltaTime / base.CoreDef.player.RunningSpeed;
|
|
_oldPosition = toMove.transform.position;
|
|
if (_needWaitToMove > 0f)
|
|
{
|
|
_needWaitToMove -= Time.deltaTime;
|
|
if (_needWaitToMove <= 0f)
|
|
{
|
|
swerveInput.activeControl(active: true);
|
|
}
|
|
return;
|
|
}
|
|
Vector3 pos = base.transform.position;
|
|
Vector3 localPos = toMove.transform.localPosition;
|
|
if (!player.winHandler.Won && !player.isDie)
|
|
{
|
|
UpdateRotationPlayerVisual();
|
|
if (!player.winHandler.isWinning || player.winHandler.moveActive)
|
|
{
|
|
swerveSmoothMove.ApplyMove(ref localPos, swerveInput.TargetWorldX, speedRatio);
|
|
}
|
|
else
|
|
{
|
|
swerveSmoothMove.ApplyMove(ref localPos, 0f, speedRatio);
|
|
}
|
|
UpdatePosY(ref localPos);
|
|
toMove.transform.localPosition = localPos;
|
|
}
|
|
if (_isTurn)
|
|
{
|
|
UpdateTurn(pos);
|
|
}
|
|
UpdateRunning(ref pos);
|
|
}
|
|
|
|
public void ChangeSpeedRatio(float richPoorValue)
|
|
{
|
|
if (base.CoreDef.player.slowSpeedWhenPoor)
|
|
{
|
|
speedRatio = richPoorValue / (float)base.CoreDef.player.maxValueRich + 1f;
|
|
}
|
|
}
|
|
|
|
private void UpdateRunning(ref Vector3 pos)
|
|
{
|
|
pos += toMove.transform.forward * (curSpeed * speedRatio * Time.deltaTime);
|
|
base.transform.position = pos;
|
|
}
|
|
|
|
private void UpdateTurn(Vector3 pos)
|
|
{
|
|
float y = _curSectionTurn.GetYRotationTurnSection(pos, _curStartYTurn, this);
|
|
base.transform.eulerAngles = new Vector3(base.transform.eulerAngles.x, y, base.transform.eulerAngles.z);
|
|
}
|
|
|
|
private void OnTurn(Section sectionTurn)
|
|
{
|
|
_curSectionTurn = sectionTurn;
|
|
_isTurn = true;
|
|
_curStartYTurn = WrapAngle(sectionTurn.transform.eulerAngles.y);
|
|
}
|
|
|
|
private static float WrapAngle(float angle)
|
|
{
|
|
angle %= 360f;
|
|
if (angle > 180f)
|
|
{
|
|
angle -= 360f;
|
|
}
|
|
return angle;
|
|
}
|
|
|
|
public void EndTurn()
|
|
{
|
|
_isTurn = false;
|
|
verti = !verti;
|
|
}
|
|
|
|
private void UpdatePosY(ref Vector3 pos)
|
|
{
|
|
if (Physics.Raycast(toMove.transform.position + Vector3.up, Vector3.down, out var hitInfo, base.CoreDef.player.maxDistRaycast, LayerGround))
|
|
{
|
|
float y = hitInfo.point.y;
|
|
if (_lastPosY - y > base.CoreDef.player.minDistSnapGround)
|
|
{
|
|
ActiveUmbrella(active: true);
|
|
y = Mathf.SmoothDamp(toMove.transform.position.y, y, ref _currentYSpeed, smoothTimeY, maxSpeedY, Time.deltaTime);
|
|
}
|
|
else
|
|
{
|
|
ActiveUmbrella(active: false);
|
|
}
|
|
pos.y = y;
|
|
_lastPosY = y;
|
|
}
|
|
}
|
|
|
|
public void Revive()
|
|
{
|
|
_desiredRotVisual = 0f;
|
|
_lastPosY = 0f;
|
|
toMove.transform.localPosition = Vector3.zero;
|
|
}
|
|
|
|
private void UpdateRotationPlayerVisual()
|
|
{
|
|
if (player.winHandler.isWinning && !player.winHandler.moveActive)
|
|
{
|
|
_desiredRotVisual = 0f;
|
|
}
|
|
else if (swerveInput.deltaX > 0f)
|
|
{
|
|
_desiredRotVisual = base.CoreDef.player.maxRot;
|
|
}
|
|
else if (swerveInput.deltaX < 0f)
|
|
{
|
|
_desiredRotVisual = 0f - base.CoreDef.player.maxRot;
|
|
}
|
|
else
|
|
{
|
|
_desiredRotVisual = 0f;
|
|
}
|
|
_desiredRotVisual = Mathf.Clamp(_desiredRotVisual, 0f - base.CoreDef.player.maxRot, base.CoreDef.player.maxRot);
|
|
Quaternion target = Quaternion.Euler(0f, _desiredRotVisual, 0f);
|
|
_visualRotation.transform.localRotation = Quaternion.Lerp(_visualRotation.transform.localRotation, target, Time.deltaTime * base.CoreDef.player.rotSpeed);
|
|
}
|
|
|
|
private void RotateWin()
|
|
{
|
|
_visualRotation.transform.localRotation = Quaternion.RotateTowards(_visualRotation.transform.localRotation, Quaternion.Euler(0f, 180f, 0f), base.CoreDef.player.rotateWinSpeed * Time.deltaTime);
|
|
}
|
|
|
|
public void WaitBeforeMove(float time)
|
|
{
|
|
_needWaitToMove = time;
|
|
swerveInput.activeControl(active: false);
|
|
}
|
|
|
|
private void OnDrawGizmos()
|
|
{
|
|
Gizmos.color = Color.magenta;
|
|
Gizmos.DrawRay(toMove.transform.position + Vector3.up, Vector3.down * base.CoreDef.player.maxDistRaycast);
|
|
}
|
|
}
|