- Home /
How to make Jedi Push and Pull objects (video)
Hello I'm looking for informations how to make something like this on video (from 9:30): http://youtu.be/lTvGIRKeRXU?t=9m30s
I would like to push and pull the cubes in one axis (x or z). I don't know how to aim the object. I think I should use gameObject.transform.position.x += something;
Could anybody help with this simple script?
Cheers!
Answer by robertbu · Dec 26, 2013 at 11:21 PM
I'm not sure if you are using Transforms or a Rigidbody. Assuming you are using a Rigidbody, then for your object:
Add a Rigidbody component
Set the 'isKinematic flag to true
Attach the following script
In the inspector, set the 'relativeOpenPos' variable.
Set the speed variable
'relativeOpenPos is the direction and distance to move the object. So if open is 1.5 units to the right, you would set it to (1.5, 0,0). If open is two units forward, then you would set it to (0,0,2).
#pragma strict
public var relativeOpenPos = Vector3(1,0,0);
public var speed = 1.0f;
private var posOpen;
private var posClose;
private var posDest;
private var open = false;
function Start() {
posClose = transform.position;
posOpen = transform.position + relativeOpenPos;
posDest = posClose;
}
function Update() {
var pos = Vector3.MoveTowards(transform.position, posDest, Time.deltaTime * speed);
rigidbody.MovePosition(pos);
}
function OpenClose() {
open = !open;
posDest = open ? posOpen : posClose;
}
Here is the code that can trigger open and closing on a mouse click. It assumes that the object is tagged 'PushPull'.
#pragma strict
function Update() {
var hit : RaycastHit;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0)) {
if (Physics.Raycast(ray, hit) && (hit.collider.tag == "PushPull")) {
hit.collider.GetComponent(PushPull).OpenClose();
}
}
}
Note if you are not using a Rigidbody, you can change line 19 to:
transform.position = pos;
Thank You very much! It works great! Could You translate this line into c# or something more simple? posDest = open ? posOpen : posClose;
I think the Rigidbody will be better, thanks for advice. I don't understand this code in 100% but I will read tomorrow more about Ray and ReycastHit. I understand the PushPull here: GetComponent(PushPull) is a name of script attached to cube?
Also where and how I can add a symbol which can inform the player about possibility to pull or push the object?
Thanks a lot! Cheers!
The line you indicate:
posDest = open ? posOpen : posClose;
...works in C#. It is equivalent to:
if (open)
posDest = posOpen;
else
posDest = posClose;
'PushPull' must be the name of the script. As for adding a symbol, how you do that code will depend on how you do the symbol. Some games use a cursor that changes. Some have a symbol that appears at a fixed location on the object (or the the object is highlighted in some way) when a raycast hit is on the object. How this works will depend on your game mechanic. You might look into using a GUITexture and using Camera.WorldToScreenPoint() from the RaycastHit to place the symbol.
Thank You very much for reply!
Could You check this code in c#? I am learning translation from JS to c# yet. It works pretty well but I'm not sure about "Send$$anonymous$$essage". Without that I have error.
using UnityEngine; using System.Collections;
public class PushPullRaycastScript : $$anonymous$$onoBehaviour {
// Update is called once per frame
void Update () {
RaycastHit hit = new RaycastHit();
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.Get$$anonymous$$ouseButtonDown(0)) {
if (Physics.Raycast(ray, out hit) && (hit.collider.tag == "PushPull")) {
hit.collider.GetComponent("PushPullScript").Send$$anonymous$$essage("OpenClose");
}
}
}
}
If I would like to send ray from center of screen I should only change Camera.main.ScreenPointToRay(Input.mousePosition); ?
Cheers!
You don't need the 'new RaycastHit()' on line 8. A RaycastHit is a struct not a class, and its values are filled in by the Raycast. $$anonymous$$ove line 9 (and 8 for that matter) between lines 11 and 12. No reason to create a ray unless the mouse button has been pressed. You are creating a ray every frame even if the user has not pressed the mouse button key. The send message should not be needed. Be sure the function you attempt to call is 'public'. Instance variables are public by default in Javascript but private by default in C#.
Thank You, good idea with moving creation of ray to if! $$anonymous$$y bad, I was only translate code without thinking :) I must be really tired... :)
With Send$$anonymous$$essage method I was fight in this way: using UnityEngine; using System.Collections;
public class PushPullRaycastScript : $$anonymous$$onoBehaviour {
// Update is called once per frame
void Update () {
if (Input.Get$$anonymous$$ouseButtonDown(0)) {
RaycastHit hit = new RaycastHit();
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit) && (hit.collider.tag == "PushPull")) {
//hit.collider.GetComponent("PushPullScript").Send$$anonymous$$essage("OpenClose");
hit.collider.GetComponent<PushPullScript>().OpenClose();
}
}
}
}
Also method OpenClose was private - now is public. $$anonymous$$aybe in c# the name of script should be in <> ins$$anonymous$$d (). I read GetComponent<>() docs but still I can't understand how it works! :) Anyway now also I don't have any errors! I am really happy!
Cheers!
Answer by MOROZAW · Dec 28, 2013 at 04:08 PM
Hello everybody, robertbu's script works very well and I am very glad about it.
I'm looking now for other push/pull script which could be used for non static objects like above but something like force to move (addForce) forward and backward the objects.
I mean something like this on the video: Video
Here is example of pushing objects: Video
Player have ability to push from him and pull to him objects (here he is pulling cube with other force - in previous video he is pulling objects like weapons / equipment / bodies). I think I should also use rigidbody here. Could someone help? As I assume here "is kinematic" must be turned off? Also I think we can use and modify the robertbu's previous script.
Best wishes in New Year! Dominik
Best to ask this as a new question rather than asked as 'Answer' to an existing question. AddForce() will introduce a number of small problems to be solved...like how to limit the movement. As a starting point, take the PushPull script and use the relativeOpenPos as a vector for applying relative force.
Good to know, I will create new Question. I would like to this objects were controlled also by physics: gravity, speed etc.
Your answer
Follow this Question
Related Questions
pulling objects across a collider 0 Answers
adding Up force 0 Answers
pulling objects 1 Answer
sucking in particles 3 Answers
pulling in objects one end, and releasing out the other 0 Answers