Solution TD 2
BallController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class BallController : MonoBehaviour
{
private Rigidbody rb;
public GameObject cubeFactory;
public float TSpeed = 100f;
private Vector2 moveValue;
private Vector3 forceVector;
void Start()
{
rb = GetComponent<Rigidbody();
}
// This is Physics, so we want a constant interval update
void FixedUpdate()
{
forceVector.Set(moveValue.x, 0, moveValue.y);
rb.AddForce(forceVector * TSpeed * Time.fixedDeltaTime);
}
// Input Action
void OnMoveBall(InputValue value)
{
moveValue = value.Get<Vector2>();
}
// Collision Management
void OnCollisionEnter(Collision collideEvent)
{
// destroy the cube
if (collideEvent.gameObject.CompareTag("Target"))
{
Debug.Log("Cube touched");
Destroy(collideEvent.gameObject);
// A message is sent to the gameObject cubeFactory to trigger the "OnCubeDestroyed" method
cubeFactory.SendMessage("OnCubeDestroyed");
}
}
}
CameraController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
// Object to follow
public GameObject baseObject;
// Initial distance between the object and the camera
private Vector3 offset;
// The offset is calculated before the ball even falls
void Start()
{
offset = transform.position - baseObject.transform.position;
}
// Camera position management after updating our sphere
void LateUpdate()
{
transform.position = baseObject.transform.position + offset;
}
}
CubeController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class CubeController : MonoBehaviour
{
private Vector3 moveVector;
public float moveSpeed = 2.0f;
// Update is called once per frame
void FixedUpdate()
{
transform.Translate(moveVector * moveSpeed * Time.fixedDeltaTime);
/** Example of different syntaxes **/
//transform.Translate(moveVector.x * moveSpeed * Time.fixedDeltaTime, 0, moveVector.z * moveSpeed * Time.fixedDeltaTime);
// This second alternative syntax is not optimized for
// our case,but shows how to integrate 3 distinct floats directly
//transform.Translate(new Vector3(moveVector.x, 0.0f, moveVector.z) * moveSpeed * Time.fixedDeltaTime);
}
// Input action
void OnMoveCube(InputValue value)
{
moveVector.Set(value.Get<Vector2>().x, 0.0f, value.Get<Vector2>().y);
}
}
DemolitionBallController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DemolitionBallController : MonoBehaviour
{
private Vector3 positionStart;
private Rigidbody rb;
public int forceToApply = 100;
void Start()
{
rb = GetComponent<Rigidbody>();
positionStart = transform.position;
}
void FixedUpdate()
{
// Rajouter une condition décroissante aléatoire permet d'avoir une impulsion sur la baoule de démolition seulement "de temps en temps"
if (impulse == 0)
{
// !!! Attention : Random.Range(minfloat, maxfloat) est inclusif : minfloat et maxfloat peuvent sortir, mais Random.Range(minInt, maxInt) est max exclusif, c'est à dire que minInt peut sortir mais pas maxInt ! Au plus, c'est maxInt-1 qui sortira.
Vector3 forceVector = new Vector3(Random.Range(-10.0f, 10.0f), 0, Random.Range(-10, 10));
rb.AddForce(forceVector * forceToApply * Time.fixedDeltaTime);
impulse = Random.Range(50, 200);
}
else
{
impulse--;
}
}
// Collisions management
void OnCollisionEnter(Collision collideEvent)
{
// By adding the tag "Player" to your sphere
// so that it is the only impact
if (collideEvent.gameObject.CompareTag("Player"))
{
// Let's return the sphere to its original place
// and remove all residual forces from the collision
// with the demolition ball
collideEvent.gameObject.transform.position = positionStart;
collideEvent.gameObject.GetComponent<Rigidbody>().rotation = Quaternion.identity;
collideEvent.gameObject.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
collideEvent.gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
}
}
}
CubeGenerator
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeGenerator : MonoBehaviour
{
private int cubeCounter = 0;
public int MAXCUBE = 10;
public GameObject cubePrefab;
private Vector3 cubeSize;
// Bounds = box on the object limits
public GameObject ground;
private Bounds groundBounds;
// If I want my microcubes to float, I set a value for the Y position
// If you don't want them to fall, consider constraining
// the position of the rigidbody in the prefab Cube.
private float offsetY = 0.35f;
void Start()
{
// the bounding box is recovered from the ground
groundBounds = ground.GetComponent<Renderer>().bounds;
// and dimensions
cubeSize = cubePrefab.GetComponent<Renderer>().bounds.size;
}
void Update()
{
//The current number of cubes present is checked...
if(cubeCounter < MAXCUBE)
{
// One is missing, create one
float x = Random.Range(groundBounds.min.x + cubeSize.x/2, groundBounds.max.x - cubeSize.x/2);
float z = Random.Range(groundBounds.min.z + cubeSize.z/2, groundBounds.max.z - cubeSize.z/2);
Vector3 newPosition = new Vector3(x, offsetY, z);
Debug.Log("Cube instanciation at [" + x + " ; " + offsetY + ";" + z + "]");
Instantiate(cubePrefab, newPosition, Quaternion.identity);
// Add +1 cube to our counter
cubeCounter++;
}
}
// Method called by the message from the script "BallController.cs"
// to take into account the destruction of a cube
//!!!! Caution: this method must be public to be called from
// another GameObject (or script)
public void OnCubeDestroyed()
{
cubeCounter--;
}
}