- Home /
Can I make one script work independent on different Game Objects?
The question is quite clear itself, but I'll make it understandable for everyone.
I have one script for NPC movement, the scipt randomize the path which NPC follows.
If I give that script to 5 different NPCs, they start walking the same way, as they working with the same randomly chosen pattern. I can easily make 20 scripts and name them like NPCWalk1, NPCWalk2, NPCWalk3 etc., but that's not the way.
I just want to know if I can make different Game Objects using the same script independent, like they're new copies without making them in folder.
Any ideas?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPC_WalkScript1 : MonoBehaviour {
System.Random losuj; //random
int WalkAni=0, IdleAni=0;
public GameObject kamera;
private float gravity = 20f;
private float vertical_Velocity;
public float speed = 1f;
private CharacterController character_Controller;
public Animator ani;
bool trybrozmowy = false;
private Vector3 plus, bok;
Vector3 move_Direction;
int ObranyKierunek=0;
bool spacerek = true;
int odpoczynek = -1;
int chodzenie = -1;
// Use this for initialization
void Start () {
losuj = new System.Random();
character_Controller = GetComponent<CharacterController>();
odpoczynek = losuj.Next(300, 781);
chodzenie = losuj.Next(60, 240);
ObranyKierunek= losuj.Next(1, 10);
WalkAni= losuj.Next(1, 9);
IdleAni = losuj.Next(1, 7);
if (ObranyKierunek==5)
{
ObranyKierunek = losuj.Next(1, 5);
}
}
// Update is called once per frame
void Update () {
if (trybrozmowy == false)
{
MoveTheNPC();
}
else
{
ani.Play("IDLE"+IdleAni);
}
transform.eulerAngles = new Vector3(0.0f, transform.eulerAngles.y, transform.eulerAngles.z);
}
void MoveTheNPC()
{
if (spacerek == true && chodzenie>0)
{
chodzenie--;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
if (ObranyKierunek == 7 || ObranyKierunek == 8 || ObranyKierunek == 9)
{
plus = new Vector3(kamera.transform.forward.x, 0.0f, kamera.transform.forward.z);
move_Direction += plus;
}
else if (ObranyKierunek == 1 || ObranyKierunek == 2 || ObranyKierunek == 3)
{
plus = new Vector3(-kamera.transform.forward.x, 0.0f, -kamera.transform.forward.z);
move_Direction += plus;
}
else
{
plus = new Vector3(0.0f, 0.0f, 0.0f);
}
if (ObranyKierunek == 1 || ObranyKierunek == 4 || ObranyKierunek == 7)
{
bok = new Vector3(-kamera.transform.right.x, 0.0f, -kamera.transform.right.z);
move_Direction += bok;
if (ObranyKierunek == 1 || ObranyKierunek == 7)
{
move_Direction /= 1.5f;
}
}
else if (ObranyKierunek == 3 || ObranyKierunek == 6 || ObranyKierunek == 9)
{
bok = new Vector3(kamera.transform.right.x, 0.0f, kamera.transform.right.z);
move_Direction += bok;
if (ObranyKierunek == 3 || ObranyKierunek == 9)
{
move_Direction /= 1.5f;
}
}
else
{
bok = new Vector3(0.0f, 0.0f, 0.0f);
}
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(move_Direction.normalized), 0.2f);
ani.Play("WALK"+WalkAni);
move_Direction *= speed * Time.deltaTime;
ApplyGravity();
character_Controller.Move(move_Direction);
move_Direction = new Vector3(0.0f, 0.0f, 0.0f);
/////////////////////////////////////////////////////////////////////////////////////////////////
}
else if(spacerek==true)
{
spacerek = false;
WalkAni = losuj.Next(1, 9);
IdleAni = losuj.Next(1, 7);
ani.Play("IDLE"+IdleAni);
chodzenie = losuj.Next(60, 240);
ObranyKierunek = losuj.Next(1, 10);
if (ObranyKierunek == 5)
{
ObranyKierunek = losuj.Next(1, 5);
}
}
else if(odpoczynek>0)
{
odpoczynek--;
}
else
{
spacerek = true;
odpoczynek = losuj.Next(300, 781);
}
}
void ApplyGravity()
{
vertical_Velocity -= gravity * Time.deltaTime;
// jump
//PlayerJump();
move_Direction.y = vertical_Velocity * Time.deltaTime;
} // apply gravity
}
Answer by Bunny83 · Jul 02, 2019 at 09:01 PM
Well, the issue is that all your NPCs are created almost at the same time. You create a System.Random object for each of your instances. However since the Random object is initialized with the current time they most likely get all the same initial seed and therefore will draw the exact same sequence of numbers.
One solution, that @Kennai suggested, is to use Unity's global UnityEngine.Random class. Since all will share the same random number generator they won't draw the same numbers.
If for some reason you want to have a seperate System.Random instance for each enemy, you have to ensure they all have different seeds. There are many ways this can be done, but most revolve around a static state that will ensure everyone gets a different seed. The simplest case is just using a static int which you initialize with a fix value. Each time one of your NPC creates his Random instance you just increment that static field and use that value as seed. Of course since the int always starts with the same value you always get the same seeds. So the first NPC that is created always gets the same seed and will move the same way each time the game is restarted.
To solve that you can simply initialize the static int also with a random number. For this you could use Unity's Random class. Another solution is to use a static System.Random instance to draw a seed for each instance Random object. However this has the potential to draw the same seed twice or multiple times, though the chances are pretty low.
Answer by Kennai · Jul 02, 2019 at 08:42 PM
Hi, @Ramlethal! Instead of System.Random, please use UnityEngine.Random
UnityEngine.Random