The beginning of the problem is standard: I'm new to C # and Unity (3 weeks). For practice, I set myself tasks and try to solve them. First, simulate a ball falling to the ground. I coped with it. Second: simulate the fall of several balls to the ground, including their collision with each other. And then I realized that I did not have enough knowledge to implement it. While the ball was alone, everything was clear. But when there are several "players" ... Problem: I have 1 script assigned to each of the balls. But each ball has its own environment, and they do not see each other. With the help of static variables, I managed to partially solve the problem, but not completely: for some reason, not all balls collide with each other, but only some. Guys, tell me how to properly organize their interaction? I mean, how to correctly receive and process data about all balls.
I have highlighted the code that is needed to implement collisions between balls:
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
some code
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
Sorry for my google.translate and thanks for help!
using System;
using UnityEngine;
public class Movement : MonoBehaviour
{
public Transform player;
public Transform ground;
public float mass;
// other Force and direction
private float force = 3f;
private float directionForceRad = 45 * (float)Math.PI / 180;
private Vector2 acceleration;
private Vector2 movementSpeed;
private Vector2 delta;
private Vector2 normal;
// parameters of ground
private float leftEdge;
private float rightEdge;
private float groundAngle;
private float cosGroundAngle;
private float sinGroundAngle;
private Boolean IsGrounded()
{
bool isGrounded = false;
float dX = cosGroundAngle * (ground.localScale.x / 2);
float dY = sinGroundAngle * (ground.localScale.x / 2);
Vector2 distance = new Vector2(dX, dY) + (Vector2)ground.position - (Vector2)player.position;
Vector2 projectionDistance = Vector2.Dot(distance, normal) * normal;
if (projectionDistance.magnitude - 0.1 <= player.localScale.y / 2)
{
isGrounded = true;
}
return isGrounded;
}
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
public class Ball
{
public string name;
public Vector2 movement;
public float mass;
public float radius;
public Vector2 position;
public Ball(GameObject obj, Vector2 mov, float weight)
{
name = obj.name;
radius = obj.transform.localScale.x / 2;
position = obj.transform.position;
movement = mov;
mass = weight;
}
}
static Ball[] allBalls;
static GameObject[] balloons;
private void CollisionOfBalloons()
{
Vector2 first, second;
for (int i = 0; i < allBalls.Length; i++)
{
for (int j = i; j < allBalls.Length; j++)
{
if (i != j)
{
if (Vector2.Distance(allBalls[i].position, allBalls[j].position) <= allBalls[i].radius + allBalls[j].radius)
{
first = (allBalls[j].mass * allBalls[j].movement) / allBalls[i].mass;
second = (allBalls[i].mass * allBalls[i].movement) / allBalls[j].mass;
allBalls[i].movement = first;
allBalls[j].movement = second;
Debug.Log("allBalls[i] = " + allBalls[i]);
Debug.Log("allBalls[j] = " + allBalls[j]);
}
}
}
}
}
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
void Start()
{
Vector2 gravity = new Vector2(0, -10);
groundAngle = ground.transform.rotation.eulerAngles.z * (float)Math.PI / 180;
cosGroundAngle = (float)Math.Cos(groundAngle);
sinGroundAngle = (float)Math.Sin(groundAngle);
leftEdge = ground.position.x - (ground.localScale.x * cosGroundAngle) / 2;
rightEdge = ground.position.x + (ground.localScale.x * cosGroundAngle) / 2;
normal = new Vector2(1 * sinGroundAngle, -1 * cosGroundAngle);
// Components before start
acceleration = new Vector2(
(force / mass) * (float)Math.Cos(directionForceRad),
(force / mass) * (float)Math.Sin(directionForceRad) + gravity.y
);
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
balloons = GameObject.FindGameObjectsWithTag("Player");
allBalls = new Ball[balloons.Length];
foreach (var item in balloons)
{
int ind = Array.IndexOf(balloons, item);
allBalls[ind] = new Ball(balloons[ind], acceleration, mass);
}
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
}
void FixedUpdate()
{
foreach (var item in allBalls)
{
if (item.name == player.name)
movementSpeed = item.movement;
}
// speed and distance
movementSpeed += acceleration * Time.deltaTime;
delta = movementSpeed * Time.deltaTime;
player.position = (Vector2)player.position + delta;
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
foreach (var item in allBalls)
{
if (item.name == player.name)
{
item.position = player.position;
item.movement = movementSpeed;
}
}
CollisionOfBalloons();
// +++++++++++++++++++++++++
// +++++++++++++++++++++++++
// check collision and change direction
if ((player.position.x > (leftEdge - player.localScale.x / 2)) &&
(player.position.x < (rightEdge + player.localScale.x / 2)) &&
IsGrounded())
{
foreach (var item in allBalls)
{
if (item.name == player.name)
{
item.movement -= 2 * (Vector2.Dot(movementSpeed, normal) * normal);
}
}
}
}
}