- Home /
 
Kinematic Child Object Jumping Above Player
Hi guys,
I'm almost there with a script that drags an object defined as a weapon to a player via physics and, if it interacts with a spherecast, is set as a non-kinematic child of the player (i.e transforms with player). However, a recurrent bug of this is that the weapon object moves to a seemingly random vector above the player following player movement yet continues to move with the player at this random vector. Any thoughts anyone?
Cheers all,
Popuppirate
 using UnityEngine;
 using System.Collections;
 
 public class Weapon_Control_Script : MonoBehaviour {
 
     public GameObject closest_weapon;
     public bool attach_weapon;
     public float distance;
 
     private GameObject player;
     private Transform p_trans;
     private Transform w_trans;
     private GameObject[] weapons;
     private Vector3 player_vect;
     private Vector3 weapon_vect;
 
     // Use this for initialization
     void Start () {
     p_trans = transform.FindChild("PlayerAttachPoint");
     attach_weapon = false;
     }
 
     
     // Update is called once per frame
     void Update () {
         if (attach_weapon == false) {
             SearchForWeapons();        
 
         }
 
         if (distance < 200f && Input.GetButtonDown ("Fire1")) {
             attach_weapon=true;        
         }
 
         if (attach_weapon == true) {
             MoveWeapon();
 
             if(Input.GetButtonDown ("Fire2")){
             DetachWeapon();
             
             }
         }
 
 }
     
 void DetachWeapon(){//Removes Child From Player And Sets Weapon As Non-Kinematic
         attach_weapon=false;
         closest_weapon.rigidbody.isKinematic=false;
         closest_weapon.transform.parent=null;
 }
 
 
 void MoveWeapon(){ //Moves Weapon Using AddForce Until Hit By Spherecast Then Made Child.
         closest_weapon.rigidbody.useGravity=false;
         RaycastHit hit;
         player_vect = p_trans.position;
         weapon_vect = w_trans.position;
 
         Vector3 direction = (weapon_vect - player_vect);
         float distance_local = Mathf.Abs (direction.sqrMagnitude);
         closest_weapon.rigidbody.AddForce (-direction * distance_local);
         bool cast = Physics.SphereCast (transform.position, 5f, transform.forward, out hit, Mathf.Infinity);
         if (cast==true && hit.collider.gameObject.name==closest_weapon.name){ {
                 closest_weapon.transform.localPosition= player_vect;
                 closest_weapon.transform.rotation=transform.rotation;
                 closest_weapon.transform.parent=transform;
                 closest_weapon.rigidbody.isKinematic=true;
             }
         }
         Debug.Log (player_vect + "," + direction);
         }
 
 
 
 
 void SearchForWeapons(){ //This works lovely jubly
 
     weapons = GameObject.FindGameObjectsWithTag ("Weapon"); 
     distance = Mathf.Infinity;                                                            
     for (int i=0; i<weapons.Length; i++) {
         Can_Pick_Up canpickupscript=weapons[i].GetComponent<Can_Pick_Up>();
             if (canpickupscript.can_pick_up==true){
                 Vector3 diff_vect = weapons [i].transform.position - transform.position;            
                 float diff_abs = Mathf.Abs (diff_vect.sqrMagnitude);                                
                 if (diff_abs < distance) {                                                            
                     closest_weapon = weapons [i];                                                    
                     distance = diff_abs;
 
                 }
             }
 
             if (w_trans==null||w_trans.name!=closest_weapon.name){
     
                 w_trans=closest_weapon.transform.FindChild("WeaponAttachPoint");
 
             }
             
         }
         Debug.Log (closest_weapon.name);
         closest_weapon.rigidbody.useGravity=true;
 }
 
 
     
 }
 
 
              Answer by popuppirate · Oct 11, 2014 at 01:26 PM
I figured out that it was the collider for the weapon hitting the landscape below it that made this error. The fixed code looks like this:
 using UnityEngine;
 using System.Collections;
 
 public class Weapon_Control : MonoBehaviour {
 
     public GameObject closest_weapon;
     public bool attach_weapon;
     public float distance;
     
     private GameObject player;
     private Transform p_trans;
     private Transform w_trans;
     private Transform e_trans;
     private GameObject[] weapons;
     private Vector3 player_vect;
     private Vector3 weapon_vect;
     private float velocity_damping=0.1f;
     
     // Use this for initialization
     void Start () {
         p_trans = transform.FindChild("PlayerAttachPoint");
         //e_trans = transform.FindChild("EmissionPoint");
         attach_weapon = false;
     }
     
     
     // Update is called once per frame
     void Update () {
         if (attach_weapon == false) {
             SearchForWeapons();        
             
         }
         
         if (distance < 200f && Input.GetButtonDown ("Fire1")) {
             attach_weapon=true;        
         }
         
         if (attach_weapon == true) {
             MoveWeapon();
             
             if(Input.GetButtonDown ("Fire2")){
                 DetachWeapon();
                 
             }
         }
 
 }
 
     //void Beam(){
 
 
 
 //    }
     
     void DetachWeapon(){
         attach_weapon=false;
         closest_weapon.rigidbody.isKinematic=false;
         closest_weapon.transform.parent=null;
     }
     
     
     void MoveWeapon(){ //Look Here!
         closest_weapon.rigidbody.useGravity=false;
         RaycastHit sphere_hit;
         bool sphere_cast = Physics.SphereCast (transform.position, 2f, transform.forward, out sphere_hit, Mathf.Infinity);
         player_vect = p_trans.position;
         weapon_vect = w_trans.position;
         Vector3 direction = (weapon_vect - player_vect);
         float direction_angle = Vector3.Angle (direction, transform.right);
         float distance_local = Mathf.Abs (direction.sqrMagnitude);
         
         closest_weapon.rigidbody.AddForce (-direction * distance_local);
         
         if (sphere_cast==true && sphere_hit.collider.gameObject.name==closest_weapon.name){
             while(Mathf.Abs(closest_weapon.rigidbody.velocity.sqrMagnitude)>0.5f && Mathf.Abs(direction_angle)>5f){
                 closest_weapon.rigidbody.velocity*=velocity_damping;
                 closest_weapon.transform.RotateAround(transform.position, transform.forward, direction_angle);
                 closest_weapon.transform.position=Vector3.MoveTowards(closest_weapon.transform.position,transform.position,Time.deltaTime);
             }                
             closest_weapon.transform.rotation=transform.rotation;
             closest_weapon.transform.localPosition= player_vect;
             closest_weapon.transform.parent=transform;
             closest_weapon.rigidbody.isKinematic=true;
             closest_weapon.collider.enabled=false;//Collider Turned Off Here
         } 
         Debug.Log (player_vect + "," + direction);
         
     }
     
     
     
     
     
     void SearchForWeapons(){ //This works lovely jubly
         
         weapons = GameObject.FindGameObjectsWithTag ("Weapon"); 
         distance = Mathf.Infinity;                                                            
         for (int i=0; i<weapons.Length; i++) {
             Can_Pick_Up canpickupscript=weapons[i].GetComponent<Can_Pick_Up>();
             if (canpickupscript.can_pick_up==true){
                 Vector3 diff_vect = weapons [i].transform.position - transform.position;            
                 float diff_abs = Mathf.Abs (diff_vect.sqrMagnitude);                                
                 if (diff_abs < distance) {                                                            
                     closest_weapon = weapons [i];                                                    
                     distance = diff_abs;
                     
                 }
             }
             
             if (w_trans==null||w_trans.name!=closest_weapon.name){
                 
                 w_trans=closest_weapon.transform.FindChild("WeaponAttachPoint");
                 
             }
             
         }
         Debug.Log (closest_weapon.name);
         closest_weapon.collider.enabled = true;//Collider Turned On Here
         closest_weapon.rigidbody.useGravity = true;
     }
 
 }
 
 
              Your answer
 
             Follow this Question
Related Questions
Make a simple tree 1 Answer
Having Parent Origin Follow Child Objects 1 Answer
using foreach transform child, unity gets stuck 2 Answers
Child of Parent 1 Answer
Parent transform 3 Answers