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*.GetComponent<Can_Pick_Up>();*
  •  	if (canpickupscript.can_pick_up==true){*
    

Vector3 diff_vect = weapons *.transform.position - transform.position;
float diff_abs = Mathf.Abs (diff_vect.sqrMagnitude);
if (diff_abs < distance) { *

closest_weapon = weapons ;
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;
_}*_

}

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*.GetComponent<Can_Pick_Up>();*
  •  	if (canpickupscript.can_pick_up==true){*
    

Vector3 diff_vect = weapons *.transform.position - transform.position;
float diff_abs = Mathf.Abs (diff_vect.sqrMagnitude);
if (diff_abs < distance) { *

closest_weapon = weapons ;
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;
_ }*_

}