The question is answered, right answer was accepted
pulling gameobjects across collider C#
this script i attach to a collider and it pulls objects accross the colliders axis i chose. so if i set it to x axis any object that enters world travel along the colliders x axis at a speed i chose. but i want any object that enters just to move across the collider without following an axis. how can i do this? here is the script i attach to the colliders. @Priyanka-Rajwanshi @Bunny83 @Kilsnus @davidcox70 @oroora6_unity @tedesignz1
private List<GameObject> pullObjects;
public Vector3 pullDirection;
public float pullSpeed;
void Start () {
pullObjects = new List<GameObject> ();
}
void Update () {
foreach (GameObject obj in pullObjects) {
obj.transform.Translate (Time.deltaTime * pullSpeed * pullDirection,transform);
}
}
public void OnTriggerEnter(Collider coll)
{
if (coll.gameObject.gameObject.tag == "Untagged") {
pullObjects.Add (coll.gameObject);
}
}
public void OnTriggerExit(Collider col)
{
if (col.gameObject.gameObject.tag == "Untagged") {
pullObjects.Remove (col.gameObject);
}
}
}
Answer by MarioSantoso · Apr 21, 2018 at 04:40 AM
Hello,
From your description, you want something like custom gravity (a pull force) that is pointing a certain axis. So better to use physics.
Create a cube (our test subject)
Add rigidbody to cube
Turn off gravity
Add a little drag (0.3 maybe)
Move the cube to x: - 30 y: 4 z:0
Next create an empty object
Add a sphere collider to that object
Turn on trigger
Add the script below
Adjust the radius: 50, pull direction: 1,0,0, and pull speed:10
PLAY
Watch as it move across
The cube will be pulled or pushed along the x axis (since we set pull direction x:1) and continue moving along that axis.
If you move the cube starting position to x: +20, the cube will be pushed.
Once you grasp the concept, play around with the pull script.
Please assign this script to the empty object
using UnityEngine;
public class PullForce : MonoBehaviour
{
public Vector3 pullDirection;
public float pullSpeed;
public float radius;
private SphereCollider _col;
private void Start()
{
_col = GetComponent<SphereCollider>();
}
private void Update()
{
_col.radius = radius;
}
private void OnTriggerStay(Collider other)
{
float _dist = Vector3.Distance(other.transform.position, transform.position);
float _ratio = _dist / radius;
other.attachedRigidbody.AddForce(pullDirection * pullSpeed * _ratio);
}
}
ya but i dont want my gameobject to follow an axis, i just want it to move across the collider to the opposite end from which it enters then stop when it exits
just add this lines to the script
private void OnTriggerExit(Collider other)
{
other.attachedRigidbody.velocity = Vector3.zero;
}
ya but it still follows an axis when it enters the collider. i dont want it to follow an axis at all. what i basically want it to do. is wherever it enters the collider it will be pulled to the opposite end of the collider from which it entered. so basically if an object enters it will be pulled to the center, once it reaches the center of the collider it will continue moving in that direction until it exits. hopefully this makes sence. so no matter where an object enters the collider it will be pulled completely occross the collider. here ill give you the bigger picture of what im trying to acomplish. so im building a tornado game right now. my tornado is made up of multiple colliders that suck up objects with the tag of "Untagged" then rotate them arround the tornado and lift the objects into the air. So now i want to make a script that only effects objects with the tag of "Pullable" i will use this script on larger objects that the tornado might pick up, because i dont want large objects to react the same as small ones. so i want the larger objects to just be sucked through the tornado and be spit out the opposite end from which they entered. the problem with the script u gave me which pulls them across an axis untill it exits is that say i make the collider pull objects allong x axis. if the tornado is moving along the x axis this will work fine becasue it will suck the objects through it, but if i change the tornadoes movment say aginst the x axis, it will ins$$anonymous$$d push objects away from the tornado which is not what i want. so i just want the script to make objects get pulled accross the collider without following a specific axis. hopefully this makes sence :D thanks!
Ahhh, ok. I understand now. Please change the code to this. It has timescale variable there because I used the script to try another thing unrelated to your question. Just leave it or you can drop it. Try and let me know
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PullForce : $$anonymous$$onoBehaviour
{
public bool useFixedDirection;
public Vector3 pullDirection;
public float timescale = 1;
public float pullSpeed;
public float radius;
private SphereCollider _col;
private Vector3 _enterDirection;
private void Start()
{
_col = GetComponent<SphereCollider>();
}
private void Update()
{
_col.radius = radius;
Time.timeScale = timescale;
}
private void OnTriggerEnter(Collider other)
{
_enterDirection = (transform.position - other.transform.position).normalized;
}
private void OnTriggerStay(Collider other)
{
float _dist = Vector3.Distance(other.transform.position, transform.position);
float _ratio = _dist / radius;
if (useFixedDirection)
other.attachedRigidbody.AddForce(pullDirection * pullSpeed * _ratio);
else
other.attachedRigidbody.AddForce(_enterDirection * pullSpeed * _ratio);
}
private void OnTriggerExit(Collider other)
{
other.attachedRigidbody.velocity = Vector3.zero;
}
}
thanks so much man man! i will let you know how it works after school! :D
Also if it is for a tornado, then when the object exits the tornado, it should start to lose it's motion and fall to earth. Then you should turn on gravity and change the ontriggerexit codes, because the one I put there will stop the object completely.
Answer by Jdogmaster · Apr 21, 2018 at 03:16 AM
so i had an idea on how to fix it but not sure how to apply it to the script. i was thinking to have the script make game objects move twards the center of the collider but instead of making them stop once they reach the middle of the collider, continue moving untill they exits the collider. this script pulls objects twards the center of the collider, how can i make it continue moving untill it exit:
private GameObject PullOBJ;
public float PullSpeed;
public float objRotationSpeed;
public float rotation;
public float PullStrength;
public void OnTriggerStay (Collider coll)
{
if (coll.gameObject.tag == "Untagged") {
PullOBJ = coll.gameObject;
PullOBJ.transform.position = Vector3.MoveTowards (PullOBJ.transform.position, this.transform.position, PullSpeed * Time.deltaTime);
PullOBJ.transform.RotateAround (transform.position, Vector3.up, Time.deltaTime * rotation);
PullOBJ.transform.Rotate (Vector3.left, 45 * Time.deltaTime * objRotationSpeed);
}
}
}
Answer by Priyanka-Rajwanshi · Apr 24, 2018 at 08:36 AM
If you want that the pulled object should carry on its motion even when it exists trigger, you would need two scripts. One on the collider that pulls the objects and other on the objects that are pulled.
public class PullCollider : MonoBehaviour
{
public float pullSpeed;
public void OnTriggerEnter(Collider coll)
{
if (coll.gameObject.gameObject.tag == "Untagged")
{
coll.GetComponent<PulledObject>().StartPull(pullSpeed, (transform.position - coll.transform.position).normalized);
}
}
}
public class PulledObject : MonoBehaviour
{
bool startPulling = false;
float pullSpeed;
Vector3 pulledDirection;
// Use this for initialization
public void StartPull(float _pullSpeed, Vector3 _pulledDirection)
{
startPulling = true;
pullSpeed = _pullSpeed;
pulledDirection = _pulledDirection;
}
// Update is called once per frame
void Update()
{
if (startPulling)
{
transform.Translate(Time.deltaTime * pullSpeed * pulledDirection);
}
}
}
hey man it works great! thnks so much but i need an OnTriggerExit function because the object continues to be pulled even after it exits the collider
im also having a problem, that if i add enough pull force to the collider to pull the object across ins$$anonymous$$d it just pulls it to the center of the collider and it just stays there
ok so i read your answer and i dont want the object to continue moving after it exits. i just want the object that enters the collider to be pulled across the collider without following an axis just if it enters it will be pulled strait across and then when it exits it will stop its movement
You can add a OnTriggerExit as below:
public void OnTriggerExit(Collider coll)
{
if (coll.gameObject.gameObject.tag == "Untagged")
{
coll.GetComponent<PulledObject>(). startPulling = false;
}
}
$$anonymous$$ake startPulling as public in PulledObject class;