I was working a 2d game on unity, I wrote a script to manage obstacles and how to spawn them and move them during the game play which I’ve provided below
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class obstacle_manager : MonoBehaviour
{
List<GameObject> obstacles;
List<Rigidbody2D> rbd;
int childCount, x;
System.Random random;
float radius;
int max_speed, min_speed, i;
// Start is called before the first frame update
void Start()
{
childCount = transform.childCount;
i = childCount-1;
radius = Mathf.Sqrt(20*20 + 10*10) * 0 + 1;
x=0;
max_speed = 5;
min_speed = 1;
random = new System.Random();
if (obstacles == null)
{
obstacles = new List<GameObject>();
}
if (rbd == null)
{
rbd = new List<Rigidbody2D>();
}
// Loop through each child and add it to the list
for (int i = 0; i < childCount; i++)
{
Transform child = transform.GetChild(i);
obstacles.Add(child.gameObject);
rbd.Add(child.gameObject.GetComponent<Rigidbody2D>());
}
foreach(GameObject obs in obstacles){
obs.SetActive(false);
}
}
// Update is called once per frame
void Update()
{
x = random.Next(100);
if (x < childCount){
GameObject obs = obstacles[x];
if(obs.activeSelf == false){
float angle = random.Next(360) * Mathf.Deg2Rad;
Vector3 posn = new Vector3(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle), 0);
obs.transform.position = posn;
//float speed = (random.Next(max_speed-min_speed) + min_speed)/10;
Vector2 impulse = new Vector2(5f,0f);//new Vector3(-speed * Mathf.Cos(angle), -speed * Mathf.Sin(angle), 0);
rbd[x].AddForce(impulse, ForceMode2D.Impulse);
Debug.Log(rbd[x].velocity);
obs.SetActive(true);
}
}
}
}
But each time I ran it, the obstacle did became active, but it’s speed was 0, and the same was given out in the console during debugging, I don’t how to proceed
I also tried changing velocity of the rigidbody by accessing the velocity attribute and reassigning it, it wasn’t helpful either
>Solution :
According to the Unity docs (https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html)
Force can only be applied to an active Rigidbody. If a GameObject is inactive, AddForce has no effect.
So if I were you I would move the obs.SetActive(true) before the rbd[x].AddForce so the Update method would look like this:
void Update()
{
x = random.Next(100);
if (x < childCount){
GameObject obs = obstacles[x];
if(obs.activeSelf == false){
float angle = random.Next(360) * Mathf.Deg2Rad;
Vector3 posn = new Vector3(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle), 0);
obs.transform.position = posn;
obs.SetActive(true);
Vector2 impulse = new Vector2(5f,0f);//new Vector3(-speed * Mathf.Cos(angle), -speed * Mathf.Sin(angle), 0);
rbd[x].AddForce(impulse, ForceMode2D.Impulse);
Debug.Log(rbd[x].velocity);
}
}
}