- Home /
Roll-A-Ball Tutorial Questions
Hi there - I'm new to the forum and a beginner, so I apologize if I'm doing this wrong!
I have gone through the Roll-a-Ball Tutorial, but now I would like to branch out and add a few bells and whistles. I had a couple of questions and was hoping people on the forum could direct me to the next steps.
Collisions When I select "Is Trigger" in the Box Collider menu, I effectively manage to make the rotating cubes disappear upon impact. However, I would like them to produce some force on impact to move the ball in another direction. How might I go about this?
Random Object Generation I created the "Pick Up" objects, according to the code, and duplicated them a number of times. What I'd like to do, though, is randomly distribute a fixed number of the objects, in different sizes and different shapes around the game environment. Is there a way to do this?
Thank you all.
Answer by Tobychappell · May 24, 2018 at 09:49 PM
"I would like them to produce some force on impact to move the ball in another direction"
Detection of Impact can be done using the OnTriggerEnter or OnCollisionEnter methods.
Applying force to a rigidbody is as simple as:
private void OnCollisionEnter(Collision collision)
{
Rigidbody body = collision.collider.GetComponent<Rigidbody>();
if (body != null)
{
body.AddForce(new Vector3(0, 1, 0));
}
}
You may want to think about ForceMode: This is the type of force that is put on the rigidbody. It changes what goes on behind the scenes in the physics engine. Like ForceMode.Acceleration ignores the mass of the rigidbody and applies the same acceleration to an object regardless of how heavy it is. ForceMode.VelocityChange is pretty much what it says, it will override current momentum and make the object sharply move in another direction. (This could be useful if you know the exact direction/position you want the ball to bounce to). The code below should make anything colliding with it move towards another target, however there could be caveats where the other object is being told to clip or move through this object.
public Transform target;
public float bounceSpeed = 10;
private void OnCollisionEnter(Collision collision)
{
Rigidbody body = collision.collider.GetComponent<Rigidbody>();
if (body != null)
{
Vector3 direction = (target.position - collision.transform.position).normalized;
body.AddForce(direction * bounceSpeed, ForceMode.VelocityChange);
}
}
"Randomly distribute a fixed number of the objects, in different sizes and different shapes around the game environment."
I'm assuming this is for some type of level creation? and not placement of pickups. Also, I'm not sure if you mean 'around' as in scattered throughout the level, or literally around, as in at the border of the level and not inside, I'm going with scattered within the level. There is a paragraph at the end commenting of random distribution of pick-ups.
Assuming that we have an empty scene with just a plane/quad/floor mesh. We can get the bounds of the area that we want to populate items inside.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WorldGenerator : MonoBehaviour
{
public List<GameObject> prefabShapes;
public Collider floor;
private Bounds floorBounds;
public string seed;
[Range(1,10000)]
public int maxObjects;
[Range(0.5f, 10)]
public float minScale;
[Range(0.5f, 10)]
public float maxScale;
[Range(0,360)]
public float minRotation;
[Range(0, 360)]
public float maxRotation;
void Start () {
floorBounds = floor.bounds;
GenerateEnvironment();
}
void GenerateEnvironment()
{
Random.InitState(seed.GetHashCode());
for (int i = 0; i < maxObjects; i++)
{
GetRandomAsset();
}
}
private GameObject GetRandomAsset()
{
int selectedIndex = Random.Range(0, prefabShapes.Count);
Vector3 forwardDirection = GetRandomRotation();
Vector3 randomScale = GetRandomScale();
Vector3 randomPosition = GetRandomPosition();
GameObject newGO = GameObject.Instantiate(prefabShapes[selectedIndex], randomPosition, Quaternion.identity, transform);
newGO.transform.LookAt(randomPosition + forwardDirection);
newGO.transform.localScale = randomScale;
return newGO;
}
private Vector3 GetRandomPosition()
{
float x = floorBounds.center.x + (floorBounds.extents.x * Random.Range(-1.0f, 1.0f));
float y = floorBounds.center.y + (floorBounds.extents.y * Random.Range(-1.0f, 1.0f));
float z = floorBounds.center.z + (floorBounds.extents.z * Random.Range(-1.0f, 1.0f));
return new Vector3(x, y, z);
}
private Vector3 GetRandomRotation()
{
float x = Random.Range(minRotation, maxRotation);
float y = Random.Range(minRotation, maxRotation);
float z = Random.Range(minRotation, maxRotation);
return new Vector3(x, y, z).normalized;
}
private Vector3 GetRandomScale()
{
float x = Random.Range(minScale, maxScale);
float y = Random.Range(minScale, maxScale);
float z = Random.Range(minScale, maxScale);
return new Vector3(x,y,z);
}
}
A random distribution can be very easy or fairly complicated depending on the requirements. A purely/very random straight-forward distribution/generation of content should be taken with caution (example: 'No Mans Sky') where you have no or little control over what the player will experience. It can create amazing experiences but probably only for 10% of the time and really boring or confusing experiences for the remainder. Pick-Ups affect the narrative of the game (e.g Health, Ammo, booby-trapped crate) depending on when the player finds them. A more complicated system would be to analyse what the player needs against the game difficulty and choose an appropriate item when the player gets within range of the Pick-Up, you could end up offering nothing at all if the player is doing really well. You could define Pick-up spawn points where they may be Helping the player or Enhancing the player. A helper may or may not have a pick up, where as an Enhancer will always have a pickup. you could also build on top of that what the future path of the player in the level is like (e.g Boss fight.)
Answer by pankocrust · May 25, 2018 at 05:14 AM
Thank you for the very thoughtful response. I just wanted to get a little clarification, because I went way off-mark while trying to implement the first part of the code.
My understanding is that the rolling ball and the "pick up" items both have Rigidbodies. In the example tutorial, we write an OnTriggerEnter function for the Player Ball, so that game object (the pick ups) are set to be inactive on impact.
I started by pasting your initial code into this same script, above the OnTriggerEnter function - my intention was that before the pick-up would be deactivated, it would send the ball flying across the screen. It created an error with the OnTriggerEnter function, and told me I needed to update my Visual Studio. So, I did. Now, the code is default opening in XCode and not giving me the same debugging interface, so I'm a bit lost.
I hate to be so helpless, but can you help redirect me a bit?
Well, I reinstalled Unity with the older version of Visual Studio and it seems to work again. Is this a known issue, though?
I'd still like to get a little more clear on where to add the OnCollisionEnter code, since it doesn't seem to go where I thought it might.
I use VS 2017 Community with the latest version of Unity. Have you tried going to Edit -> Preferences. In one of the sections there is a dropdown list for selecting which program to use for scripting. If visual studio isn't listed you can add visual studio to it. You'll want to select the path to the dev.exe application. It'll be somewhere like Program Files -> Visual Studio 2017 -> then possibly one two more folders in until you find dev.exe.
It seems like the full version of 7.51 causes some sort of installation error and basically leaves VS in some kind of limbo where you're unable to access it, unless you just reinstall the whole thing. Unity works fine with the in-package VS, though.
If the collider of the pickup has IsTrigger set to true, then you would need to use the OnTriggerEnter method ins$$anonymous$$d, you can just rename that method and change the input parameter Collision to Collider and how it's used accordingly. Also the code i gave was just an example of what you might want to do on the collision/trigger. The ball should be shot towards the transform target. I probably should have put a null check in there too.
Your answer
![](https://koobas.hobune.stream/wayback/20220612163346im_/https://answers.unity.com/themes/thub/images/avi.jpg)