- Home /
Script stops working when on multiple objects
Hopefully i can get some help with this, its been driving me nuts for a couple of days. I'm working on an archery game, my bow and arrow scripts are almost perfect but my ai script is all messed up. I'm sure its just something stupid i set up wrong but anyways, the issue is, i have my script setup to where if an arrow hits certain parts of the ragdoll character it will execute different actions, for example if you get a headshot the character will instantly ragdoll and die. Another example, if you shoot the legs it will cripple the ai to a crawl and play the crawling animation. The problem happens when i spawn in two ai at once, the script works fine if i have only one alive ai in the scene. if i have more than one ai in the scene some of the ai are unresponsive to the arrow when it collides with them and they just keep walking towards the next path node. Heres my code.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class aiController : MonoBehaviour { float rotSpeed = 5f; private float speed = 2; private Transform target; private int wavepointIndex=0; public bool canMove = true; public static aiController instance; private bool canScare = true; private bool walking = false; private bool armBroken = false; private bool groinHurt = false; private bool isDead = false;
private GameObject ai;
private Animator aiAnim;
public AudioSource hurt_brathing;
public AudioSource lol;
void Start()
{
ai = GetComponent<GameObject>();
instance = this;
target = pathNodesController.pathNodes[0];
aiAnim = GetComponent<Animator>();
}
void Update()
{
if(isDead==true)
{
lol.Stop();
hurt_brathing.Stop();
}
if(speed >= 1.90)
{
aiAnim.SetBool("walking", true);
}
if (canMove == true)
{
Vector3 dir = target.position - transform.position;
transform.Translate(dir.normalized * speed * Time.deltaTime, Space.World);
var targetRotation = Quaternion.LookRotation(target.transform.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotSpeed * Time.deltaTime);
if (Vector3.Distance(transform.position, target.position) <= 0.05f)
{
aiAnim.SetBool("walking", false);
GetNextPathNode();
}
}
}
void GetNextPathNode()
{
if(wavepointIndex >= pathNodesController.pathNodes.Length-1)
{
Debug.Log("last Path Node");
return;
}
wavepointIndex++;
target = pathNodesController.pathNodes[wavepointIndex];
}
void OnTriggerEnter(Collider other)
{
if(other.tag ==("Scare") && canScare == true)
{
aiAnim.SetBool("sprinting", true);
speed = 4f;
}
}
public void breakLegs()
{
aiAnim.SetBool("sprinting", false);
canScare = false;
aiAnim.SetBool("crawl", true);
speed = 0.5f;
if (hurt_brathing.isPlaying == false&&isDead==false)
{
hurt_brathing.Play();
}
}
public void ragDoll()
{
isDead = true;
aiAnim.enabled = false;
Rigidbody[] bodies = GetComponentsInChildren<Rigidbody>();
for (int i = 0; i < bodies.Length; i++)
{
bodies[i].isKinematic = false;
}
StartCoroutine(destroyAI());
}
IEnumerator destroyAI()
{
yield return new WaitForSeconds(50000 * Time.deltaTime);
Destroy(gameObject);
}
public void BreakLeftArm()
{
if (armBroken == false)
{
aiAnim.SetBool("leftArm", true);
speed = 1;
if (hurt_brathing.isPlaying == false && isDead == false)
{
hurt_brathing.Play();
}
}
canScare = false;
armBroken = true;
}
public void BreakRightArm()
{
if (armBroken == false)
{
aiAnim.SetBool("RightArm", true);
speed = 1;
if(hurt_brathing.isPlaying==false && isDead == false)
{
hurt_brathing.Play();
}
}
canScare = false;
armBroken = true;
}
public void HitGroin()
{
if(groinHurt==false)
{
lol.Play();
}
}
}
heres an example from my arrow script, howw i execute the code in the ai controller.
if (collision.collider.tag == "Head")
{
aiController.instance.ragDoll();
aiController.instance.canMove = false;
transform.SetParent(collision.collider.transform);
Destroy(rbarrow);
if (hasHit == false)
{
Instantiate(bloodFX[Random.Range(0, bloodFX.Length)], bloodSpwaner.position, bloodSpwaner.rotation);
Instantiate(bloodFxSkin, bloodSkinSpawner.position, bloodSkinSpawner.rotation, transform.parent);
Instantiate(bloodSprayFx, bloodSkinSpawner.position, bloodSkinSpawner.rotation, transform.parent);
}
hasHit = true;
}
Answer by XxCAFxX · Dec 30, 2018 at 06:18 AM
Thank you to @Razor1994 for confirming that it was because i was using an instance to call my functions. I managed to figure it out myself. if anyone was having this issue this was my solution, instead of calling aiController.instance.ragDoll(); i instead called:
collision.collider.gameObject.GetComponentInParent().ragDoll();
The script now works as it should (:
Answer by Razor1994 · Dec 30, 2018 at 03:08 AM
I would say the last ai that has been spawned will always work. And thats because you have a static reference to yourself (singleton pattern). With every new aiController instance you override that instance.
public static aiController instance;
instance = this;
so all your other aiController instances will now reference the latest aiController instance.
Thanks for the response, i figured it was something to do with the way im accessing it through the other script, but how would i go about fixing this while retaining the ability to access the ai controller from my arrow controller?
I believe you need to either duplicate the controller and forgo the singleton or abstract the controller into a system that operates on the individual characters.