A game about forced loneliness, made by TACStudios
1using System.Collections;
2using UnityEngine.InputSystem;
3using UnityEngine;
4using UnityEngine.InputSystem.Interactions;
5
6// Using simple actions with callbacks.
7public class SimpleController_UsingActions : MonoBehaviour
8{
9 public float moveSpeed;
10 public float rotateSpeed;
11 public float burstSpeed;
12 public GameObject projectile;
13
14 public InputAction moveAction;
15 public InputAction lookAction;
16 public InputAction fireAction;
17
18 private bool m_Charging;
19
20 private Vector2 m_Rotation;
21
22 public void Awake()
23 {
24 // We could use `fireAction.triggered` in Update() but that makes it more difficult to
25 // implement the charging mechanism. So instead we use the `started`, `performed`, and
26 // `canceled` callbacks to run the firing logic right from within the action.
27
28 fireAction.performed +=
29 ctx =>
30 {
31 if (ctx.interaction is SlowTapInteraction)
32 {
33 StartCoroutine(BurstFire((int)(ctx.duration * burstSpeed)));
34 }
35 else
36 {
37 Fire();
38 }
39 m_Charging = false;
40 };
41 fireAction.started +=
42 ctx =>
43 {
44 if (ctx.interaction is SlowTapInteraction)
45 m_Charging = true;
46 };
47 fireAction.canceled +=
48 ctx =>
49 {
50 m_Charging = false;
51 };
52 }
53
54 public void OnEnable()
55 {
56 moveAction.Enable();
57 lookAction.Enable();
58 fireAction.Enable();
59 }
60
61 public void OnDisable()
62 {
63 moveAction.Disable();
64 lookAction.Disable();
65 fireAction.Disable();
66 }
67
68 public void OnGUI()
69 {
70 if (m_Charging)
71 GUI.Label(new Rect(100, 100, 200, 100), "Charging...");
72 }
73
74 public void Update()
75 {
76 var look = lookAction.ReadValue<Vector2>();
77 var move = moveAction.ReadValue<Vector2>();
78
79 // Update orientation first, then move. Otherwise move orientation will lag
80 // behind by one frame.
81 Look(look);
82 Move(move);
83 }
84
85 private void Move(Vector2 direction)
86 {
87 if (direction.sqrMagnitude < 0.01)
88 return;
89 var scaledMoveSpeed = moveSpeed * Time.deltaTime;
90 // For simplicity's sake, we just keep movement in a single plane here. Rotate
91 // direction according to world Y rotation of player.
92 var move = Quaternion.Euler(0, transform.eulerAngles.y, 0) * new Vector3(direction.x, 0, direction.y);
93 transform.position += move * scaledMoveSpeed;
94 }
95
96 private void Look(Vector2 rotate)
97 {
98 if (rotate.sqrMagnitude < 0.01)
99 return;
100 var scaledRotateSpeed = rotateSpeed * Time.deltaTime;
101 m_Rotation.y += rotate.x * scaledRotateSpeed;
102 m_Rotation.x = Mathf.Clamp(m_Rotation.x - rotate.y * scaledRotateSpeed, -89, 89);
103 transform.localEulerAngles = m_Rotation;
104 }
105
106 private IEnumerator BurstFire(int burstAmount)
107 {
108 for (var i = 0; i < burstAmount; ++i)
109 {
110 Fire();
111 yield return new WaitForSeconds(0.1f);
112 }
113 }
114
115 private void Fire()
116 {
117 var transform = this.transform;
118 var newProjectile = Instantiate(projectile);
119 newProjectile.transform.position = transform.position + transform.forward * 0.6f;
120 newProjectile.transform.rotation = transform.rotation;
121 var size = 1;
122 newProjectile.transform.localScale *= size;
123 newProjectile.GetComponent<Rigidbody>().mass = Mathf.Pow(size, 3);
124 newProjectile.GetComponent<Rigidbody>().AddForce(transform.forward * 20f, ForceMode.Impulse);
125 newProjectile.GetComponent<MeshRenderer>().material.color =
126 new Color(Random.value, Random.value, Random.value, 1.0f);
127 }
128}