-
Notifications
You must be signed in to change notification settings - Fork 0
/
BirdStateMachine.cs
173 lines (138 loc) · 4.33 KB
/
BirdStateMachine.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class BirdStateMachine : MonoBehaviour
{
#region States
private BirdBaseState currentState;
public BirdGlideState GlideState = new BirdGlideState();
public BirdFlapState FlapState = new BirdFlapState();
public BirdFallState FallState = new BirdFallState();
public BirdDeathState DeathState = new BirdDeathState();
#endregion
private bool _isDead = false;
public bool DeadBird => _isDead;
public BarSystem energy;
#region Variables
[SerializeField] private InputAction _controller;
[SerializeField] private GameObject _model;
private Rigidbody _rb;
private BoxCollider _collider;
public Animator anim;
public Vector2 GetInput => _controller.ReadValue<Vector2>();
public Rigidbody GetRigidbody => _rb;
#endregion
#region Bird Variables
// All the variables in this region can be replaced with a 'Scriptable object'
[SerializeField] private float _curSpeed = 0f;
private float _rotationSpeed = 5.0f;
[SerializeField] private float _heightGain = 200f;
private float _flapForce = 400f;
[SerializeField] private AnimationCurve _dropOff;
private float _liftSpeed = 30f;
private float _minSpeed = 20f;
private float _maxSpeed = 100f;
private float _turnAmount = 40f;
private float _rollAmount = 45f;
//private float _turnForce = 0f;
public float LiftSpeed => _liftSpeed;
public float HeightGain => _heightGain;
public float FlapForce => _flapForce;
#endregion
public float CurrentSpeed
{
get
{
return _curSpeed;
}
set
{
if (!_isDead)
{
value = Mathf.Clamp(value, _minSpeed, _maxSpeed);
}
_curSpeed = value;
}
}
public Vector2 BirdVector()
{
Vector2 velocity = new Vector2(GetInput.x * _turnAmount / (_turnAmount * 2f), (_curSpeed / (_maxSpeed * 2f)));
//Debug.Log(velocity);
return velocity;
}
public float SpeedMagnitude()
{
return (_curSpeed / _maxSpeed) * 0.1f;
}
public float SpeedFallOff()
{
float artificialDrag = _dropOff.Evaluate((_curSpeed - _minSpeed) / _maxSpeed) * 0.2f;
//Debug.Log(artificialDrag);
return artificialDrag;
}
public enum WingStates
{
None = 0,
Resting = 1,
Flap,
Glide,
}
public WingStates birdState = WingStates.None;
private void OnEnable()
{
_controller.Enable();
}
private void OnDisable()
{
_controller.Disable();
}
// Start is called before the first frame update
private void Awake()
{
_curSpeed = _minSpeed;
_rb = GetComponent<Rigidbody>();
}
private void Start()
{
currentState = GlideState;
currentState.EnterState(this);
}
// Update is called once per frame
private void Update()
{
currentState.UpdateState(this);
}
private void OnTriggerEnter(Collider other)
{
currentState.OnTrigger(this, other);
}
private void FixedUpdate()
{
currentState.PhysicsUpdateState(this);
BirdRotation();
}
public void SwitchState(BirdBaseState state)
{
currentState = state;
state.EnterState(this);
}
public void UpdateAnimationState(WingStates state)
{
birdState = state;
anim.SetInteger("CurState", (int)state);
}
private void BirdRotation()
{
float pitchAngle = Mathf.LerpAngle(_model.transform.rotation.eulerAngles.x, Mathf.Clamp(-_rb.velocity.y, -70, 80), Time.deltaTime * _rotationSpeed);
//float yawAngle = Mathf.LerpAngle(transform.rotation.eulerAngles.y, Mathf.Clamp(playerInput.x * turnAmount, -turnAmount, turnAmount), Time.deltaTime * rotationSpeed);
float rollAngle = Mathf.LerpAngle(-_model.transform.rotation.eulerAngles.z, Mathf.Clamp(GetInput.x * _rollAmount, -_rollAmount, _rollAmount), Time.deltaTime * _rotationSpeed * 0.5f);
_model.transform.rotation = Quaternion.Euler(pitchAngle, 0f, -rollAngle);
}
public void BirdDead()
{
_isDead = true;
SwitchState(DeathState);
FindObjectOfType<GameManager>().EndGame();
}
}