Good evening everyone,
Imagine I can control a game object “character”. He is in a center of a game object named “Sphere” (the sphere acts as a detection zone for the character).
There are also a lot of game objects named “Neutre” around my character. Each of them have a “controlPion” script attached, which is deactivated.
I want to activate “controlPion” on one “Neutre” when I press button A (xbox controller), only if this Neutre is colliding with the Sphere.
Here is my method to do it, and below you can find my code:
-
Add all game objects which are coliding with the sphere in an array
-
Choose, in the array, a random game object which contain “Neutre” on his name
-
If I press button A, activate script “controlPion” on this game object.
My code isn’t working but I have no error in the console (I didn’t write step 3, but step 1 and 2 should work without it). I also don’t know if my method is a good way to solve my problem.
Any hints / advices are appreciated ^^
function Start () {
}
function OnTriggerEnter(myTrigger : Collider) {
//If a game object collide with "Sphere", put it in an array
if(myTrigger.gameObject.name == "Sphere"){
Debug.Log("Object in Sphere");
var objects = FindObjectsOfType(GameObject);
var controlArray1 = new Array();
//Choose only game object with "Neutre" in their names
for (var obj : GameObject in objects) {
if (obj.name.Contains("Neutre")) {
Debug.Log("Neutre in Sphere");
controlArray1.Add(obj);
Debug.Log("Neutre in Array");
}
}
}
//If I press button A, choose a random game object in array
if(Input.GetKeyDown("joystick button 0")){
var MyIndex = Random.Range(0, controlArray1.length);
Debug.Log("Neutre chosen");
}
}
Thanks a lot.
Which object is this script applied to? OnTriggerEnter is called at the moment of first contact, on the object which has the trigger collider, and the paramter myTrigger is set to the collider of the other object. Since you check the other object for the name “Sphere”, the first “if” condition would only be met if you have this script on the Neutre objects.
I wouldn’t use OnTriggerEnter in this case, because it is called at the moment of first contact, so only for one frame, and once the Neutre is inside the sphere it will not be called again until the Neutre gets out and then in again. You would have to keep adding the colliders entering the sphere in your own array outside of the function or, much easier, just go through all objects inside the sphere at the moment of button press:
void Update()
{
if (Input.GetKeyDown("joystick button 0"))
{
var hitColliders = Physics.OverlapSphere(transform.position, radius);
for (var i = 0; i < hitColliders.Length; i++)
{
// Go through the colliders, add those which are Neutre to an array,
// then select from the array
}
}
}
OverlapSphere is a good alternative, but has a small problem: it returns objects whose bounding boxes intersect the sphere - in many cases the corner of the bounding box touches the sphere, but the object body actually doesn’t. If you need more precision, try the following logic: inside OnTriggerEnter, verify whether the object entering the trigger has “Neutre” in its name; if so, add it to the list; inside OnTriggerExit, remove the element from the list; when A is pressed, select a random object from the list and enable the script. Additionally, it would be better to use List instead of the problematic and slow Array class:
import System.Collections.Generic;
var neutres = new List.<GameObject>();
function OnTriggerEnter(other: Collider){
if (other.name.Contains("Neutre")){ // if Neutre entered trigger...
neutres.Add(other.gameObject); // add it to the list
}
}
function OnTriggerExit(other: Collider){
if (other.name.Contains("Neutre")){ // if Neutre object left trigger...
neutres.Remove(other.gameObject); // remove it from the list
}
}
function Update(){
// if button pressed and there are neutres in the list...
if (Input.GetKeyDown("joystick button 0") && neutres.Count > 0){
// select a random one and enable its script:
var selNeutre: GameObject = neutres[Random.Range(0, neutres.Count)];
selNeutre.GetComponent(controlPion).enabled = true;
}
}
NOTE: If Sphere is a moving trigger, remember to add a kinematic rigidbody to it - moving triggers must have a rigidbody in order to detect collisions.