summaryrefslogtreecommitdiffhomepage
path: root/Assets/Scripts/MovingSphere.cs
blob: a839ca73599ee72cdb96148fe57634c13f709e47 (plain)
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovingSphere : MonoBehaviour
{
	Rigidbody body;

	[SerializeField, Range(1f, 100f)]
	float maxSpeed = 10f;
	[SerializeField, Range(1f, 100f)]
	float maxAcceleration = 10f;
	[SerializeField, Range(1f, 100f)]
	float maxAirAcceleration = 1f;
	Vector3 velocity;

	[SerializeField, Range(0f, 10f)]
	float jumpHeight = 2f;
	[SerializeField, Range(0, 5)]
	int maxAirJumps;
	bool desiredJump;
	int jumpPhase;
	bool onGround;

	// 0.0 means walls
	// 1.0 means floors
	float maxJumpAngle = 0.1f; 

	Vector3 inputVelocity;

	// Start is called before the first frame update
	void Awake()
	{
		body = GetComponent<Rigidbody>();
	}

	// Update is called once per frame
	void Update()
	{
		Vector2 playerInput = new Vector2(
				Input.GetAxis("Horizontal"),
				Input.GetAxis("Vertical")
				);
		playerInput = Vector2.ClampMagnitude(playerInput, 1f);

		desiredJump |= Input.GetButtonDown("Jump");

		inputVelocity = new Vector3(playerInput.x, 0f, playerInput.y);

	}

	void FixedUpdate()
	{
		UpdateState();
		Vector3 acceleration = new Vector3(
				inputVelocity.x,
				0f,
				inputVelocity.z
				);

		if(onGround)
			acceleration *= maxAcceleration;
		else
			acceleration *= maxAirAcceleration;

		velocity += acceleration * Time.deltaTime;
		velocity = Vector3.ClampMagnitude(velocity, maxSpeed);

		if(desiredJump)
		{
			Debug.Log("Attempted Jump!");
			desiredJump = false;
			Jump();
		}

		body.velocity = velocity;

		onGround = false;
	}

	void UpdateState()
	{
		velocity = body.velocity;
		if(onGround)
			jumpPhase = 0;
	}

	void Jump()
	{
		if(onGround || jumpPhase < maxAirJumps)
		{
			Debug.Log("Jump!");
			jumpPhase += 1;
			float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight);
			if(velocity.y > 0f)
				jumpSpeed = Mathf.Max(jumpSpeed - velocity.y, 0f);
			velocity.y += jumpSpeed;
		}
	}

	void OnCollisionStay(Collision collision) {
		EvaluateCollision(collision);  
	}

	void OnCollisionEnter(Collision collision) {
		EvaluateCollision(collision);  
	}

	void EvaluateCollision(Collision collision) {
		for (int i = 0; i < collision.contactCount; i++) {
			Vector3 normal = collision.GetContact(i).normal;
			onGround |= normal.y >= maxJumpAngle;
		}
	}
}