Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Mesh moves away from enemy character

Discussion in 'Scripting' started by omega_volta, Jul 6, 2021.

  1. omega_volta

    omega_volta

    Joined:
    Apr 28, 2021
    Posts:
    15
    I'm making an enemy character for my game that uses NavMesh for movement and turns into a Ragdoll upon death. After implementing the Ragdoll feature, I've faced several issues that interrupts the functionality of the enemy. I had a problem where the Body would be separated from the empty parent object and stutter in mid-air. I fixed this by making a separate script for the ragdoll, and the enemy's body stays still upon death. However, when the enemy isn't dead, its mesh would move away from its actual location, despite it saying that it's still there in the editor. Help would be greatly appreciated.

    The mesh before the game starts:
    Screen Shot 2021-07-06 at 4.00.11 pm.png


    the mesh's location after the game starts:
    Screen Shot 2021-07-06 at 4.00.02 pm.png


    the body's inspector tab (ignore the fact that the mesh is right hand, its just the name of the body, don't ask)
    Screen Shot 2021-07-06 at 4.00.34 pm.png

    The main enemy parent's inspector tab:
    Screen Shot 2021-07-06 at 4.00.43 pm.png

    the enemy's hierarchy:
    Screen Shot 2021-07-06 at 4.01.20 pm.png


    The enemy's main script:
    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using UnityEngine.AI;
    7.  
    8. public class NewZombieScript : MonoBehaviour
    9. {
    10.     public float ZombieChaseSpeed = 8;
    11.     public float ZombieWanderSpeed = 4;
    12.     public float ZombieRotationSpeed = 5;
    13.     public float MaxDistzombie = 32.1f; // if larger than this, don't chase, otherwise, chase if lower than this and higher than MinDistzombie
    14.     public float MinDistzombie = 3; // if larger than this and smaller than MaxDistzombie, chase player
    15.     public Transform target;
    16.     public bool chasing;
    17.     private bool Alive;
    18.     public Rigidbody rb;
    19.     public float PlayerDistance;
    20.    
    21.  
    22.     public int MaxZombieHP = 50;
    23.     public int CurrentZombieHP;
    24.     public HealthBar ZombieHealthBar;
    25.     public Animator ZombieAnimator;
    26.  
    27.     public NavMeshAgent agent;
    28.  
    29.     public GameObject body;
    30.  
    31.     private float attackTime; //time since last attack
    32.     public const float attackRate = 1f; // attack cooldown
    33.  
    34.     private void Awake()
    35.     {
    36.         chasing = false;
    37.         Alive = true;
    38.     }
    39.  
    40.    
    41.  
    42.     public void Damage(int ZombieDamage)
    43.     {
    44.         CurrentZombieHP -= ZombieDamage;
    45.         ZombieHealthBar.SetHealth(CurrentZombieHP);
    46.     }
    47.  
    48.  
    49.     // Start is called before the first frame update
    50.     void Start()
    51.     {      
    52.         Alive = true;
    53.  
    54.         CurrentZombieHP = MaxZombieHP;
    55.  
    56.         ZombieAnimator = GetComponentInChildren<Animator>();
    57.  
    58.         ZombieAnimator.enabled = true;
    59.  
    60.         body.GetComponent<ZombieRagDoll>().RagDollStatus(true);
    61.  
    62.         rb = GetComponent<Rigidbody>();
    63.  
    64.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    65.  
    66.         agent.enabled = true;
    67.  
    68.     }
    69.  
    70.     // Update is called once per frame
    71.     void Update()
    72.     {
    73.      
    74.         PlayerDistance = Vector3.Distance(target.position, transform.position);
    75.  
    76.        
    77.  
    78.         if (Alive == true)
    79.         {
    80.             if (Input.GetKeyDown(KeyCode.M))
    81.             {
    82.                 Damage(8);
    83.             }
    84.  
    85.             if (PlayerDistance <= MaxDistzombie)
    86.             {
    87.                
    88.                 if (PlayerDistance > MinDistzombie)
    89.                 {
    90.                     GoToTarget();
    91.                     agent.speed = ZombieChaseSpeed;
    92.                     chasing = true;
    93.                     Debug.Log("Chasing");
    94.                 }
    95.             }
    96.             if (PlayerDistance < MinDistzombie)
    97.             {
    98.                 StopZombie();
    99.                 ZombieAttack();
    100.             }
    101.         }
    102.        
    103.    
    104.  
    105.  
    106.         if (attackTime > 0)
    107.         {
    108.             attackTime -= Time.deltaTime;
    109.         }
    110.  
    111.  
    112.  
    113.  
    114.         void GoToTarget()
    115.         {
    116.             if (Alive == true)
    117.             {
    118.                 if (PlayerDistance > MinDistzombie)
    119.                 {
    120.                     ZombieChaseSpeed = 4f;
    121.                     chasing = true;
    122.                     Debug.Log("Chasing");
    123.                 }
    124.             }          
    125.         }
    126.  
    127.         if (CurrentZombieHP <= 0)
    128.         {
    129.             Die();
    130.         }
    131.  
    132.  
    133.  
    134.  
    135.         if (chasing)
    136.         {
    137.             //rotate to look at the player
    138.  
    139.             if (Alive == true)
    140.             {
    141.                 //move towards the player
    142.                 FaceTarget();
    143.                 ZombieAnimator.SetTrigger("FoundTarget");
    144.                 agent.SetDestination(target.position);
    145.  
    146.  
    147.                 Debug.Log("MovingToPlayer");
    148.  
    149.                 if (PlayerDistance > MaxDistzombie)
    150.                 {
    151.                     chasing = false;
    152.                     ZombieAnimator.SetTrigger("LostTarget");
    153.  
    154.                     //give up when out of range
    155.                 }
    156.  
    157.             }
    158.  
    159.             if (Alive == false)
    160.             {
    161.                 chasing = false;
    162.             }
    163.  
    164.  
    165.         }
    166.  
    167.  
    168.  
    169.         else
    170.         {
    171.             //not currently chasing
    172.  
    173.             //start chasing when player is close enough
    174.             agent.speed = ZombieWanderSpeed;
    175.            
    176.         }
    177.  
    178.  
    179.         void StopZombie()
    180.         {
    181.             chasing = false;
    182.             agent.speed = 0f;
    183.             Debug.Log("StoppedMoving");
    184.         }
    185.  
    186.         void FaceTarget ()
    187.         {
    188.             Vector3 direction = (target.position - transform.position).normalized;
    189.             Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
    190.             transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5f);
    191.         }
    192.        
    193.  
    194.         void ZombieAttack()
    195.         {
    196.             if (attackTime <= 0)
    197.             {
    198.                 attackTime = attackRate;
    199.                 target.GetComponent<PlayerHealth>().TakeDamage(8);
    200.                 Debug.Log("AttackingPlayer");
    201.             }
    202.  
    203.         }
    204.     }
    205.  
    206.    
    207.     void Die()
    208.     {
    209.         body.GetComponent<ZombieRagDoll>().RagDollStatus(true);
    210.         ZombieCollider(true);
    211.         Alive = false;
    212.         ZombieHealthBar.gameObject.SetActive(false);
    213.         ZombieAnimator.enabled = false;
    214.     }
    215.  
    216.     private void ZombieCollider(bool state)
    217.     {
    218.         Collider[] colliders = body.GetComponentsInChildren<Collider>();
    219.  
    220.         foreach (Collider collider in colliders)
    221.         {
    222.             collider.enabled = state;
    223.         }
    224.         GetComponent<Collider>().enabled = state;
    225.     }
    226.  
    227.  
    228.     void OnDrawGizmosSelected()
    229.     {
    230.         Gizmos.color = Color.red;
    231.         Gizmos.DrawWireSphere(transform.position, MaxDistzombie);
    232.  
    233.         Gizmos.color = Color.blue;
    234.         Gizmos.DrawWireSphere(transform.position, MinDistzombie);
    235.     }
    236.  
    237. }
    238.  
    the ragdoll script:
    Code (csharp):
    1.  
    2. sing System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.AI;
    6.  
    7. public class ZombieRagDoll : MonoBehaviour
    8. {
    9.    
    10.     public Animator ZombieAnimator;
    11.  
    12.  
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         ZombieAnimator = GetComponentInChildren<Animator>();
    17.         RagDollStatus(false);
    18.         ZombieAnimator.enabled = true;
    19.     }
    20.  
    21.  
    22.     // Update is called once per frame
    23.     void Update()
    24.     {
    25.        
    26.     }
    27.  
    28.     public void RagDollStatus(bool state)
    29.     {
    30.         Rigidbody[] rigidbodies = GetComponentsInChildren<Rigidbody>();
    31.  
    32.         foreach (Rigidbody rigidbody in rigidbodies)
    33.         {
    34.             rigidbody.isKinematic = !state;
    35.         }
    36.         GetComponent<Animator>().enabled = !state;
    37.     }
    38.  
     
  2. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    Hello what is inside BodyZ? in your hierachy?There are some objects with mesh? What is their position?

    If i was you 1st i find all child objects what have mesh and set them to new Vector3(0,0,0) of parent.Also you can try position and local position i am not very experienced but you can find difference in documentation.

    Also start game , select object what position you dont like, and move it to desired position and you will see what position of what object you want.


    "localPosition is the position of the GameObject with respect to its parent object. transform. position is the position of the GameObject with respect to the root. Within local space of a GameObject, the center (or pivot) is always (0, 0, 0)"



    Code (CSharp):
    1. foreach(Trainsform item in YourParentGameObject.transform){
    2. item.transform.position = new Vector3(0,0,0);
    3. }
     
    Last edited: Jul 6, 2021
  3. omega_volta

    omega_volta

    Joined:
    Apr 28, 2021
    Posts:
    15
    BodyZ originally contained the models for the enemy's feet and hands. I used blender to make the enemy and created the feet and hands separately. This was until i merged the feet and hands with the main body and made it a singular object. The children inside BodyZ are all disabled.
     
  4. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    So any change? did you find hot to fix it?
     
  5. omega_volta

    omega_volta

    Joined:
    Apr 28, 2021
    Posts:
    15
    No. Not yet. BodyZ is in the same position as the parent, but for some reason, the mesh itself is what's moving.