Sorry for this post, I’ve been looking for an answer without luck…
If someone can provide some light one this I will appreciate it… Im new to this… so … :S
I have an inclined object, and on its surface some other are rolling… I want to be able to touch them and roll them up on the direction of where I move the touch, of course, if I move the finger more the object should go upwards more and vice versa.
this is what I have so far…
var objectTransform : Transform;
function Start(){
objectTransfrom = transform;
}
function Update () {
print("Object is moving X: " + objectTransform.position.x +"Y:"+objectTransform.position.y);
for(touch in Input.touches){
if(Input.touchCount == 1 TouchPhase.Moved == touch.phase){
rigidbody.AddForce(objectTransform.forward * 100);
}
}
}
So to better explanation… the goal is to have an angled surface wehre a ball can roll down… but that ball is attached to another object via a chain/rope, this rope pass over a pulley and on the other end there is another object attached… so what I want is to move the ball up/down so the other mass will go up/down. I dunno what else should I have into consideration to achieve this simulation.
So far Im trying to move the ball without anything attached, just move the ball up the surface and when released the finger the ball should go down over the surface once again.
I hadn’t been able to do that…
this another try out, basically I wanted to to take the ball and tell the rigidbody to dont be affected by gravity as to don’t allow it to fall during the process. then if the finger moved I needed to move the ball up or down… BUT REMEMBER THE SURFACE IS ANGLED BY 45 degrees. So i can’t make a translation only over the y axis, otherwise will go just upwards perpendicular to the scene’s plane. then finally when I release the finger, I allow the rigidbody to use gravity.
function Update () {
for(touch in Input.touches){
if(Input.touchCount == 1){
var r = Camera.main.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0f));
var hit : RaycastHit;
if (!Physics.Raycast(r, hit, 100f)) return;
if (hit.collider.name == "Sphere")
{
if( TouchPhase.Began == touch.phase){
print("BEGAN");
hit.rigidbody.useGravity = false;
previousTouchPosition = touch.position;
}
else if (TouchPhase.Moved == touch.phase){
//var x : float = touch.position.x - previousTouchPosition.x;
var y : float = touch.position.y * Time.deltaTime * speed;
// objectTrans.position.x += x;
objectTrans.Translate (0,y,0);
//objectTrans.position = touch.deltaPosition;
previousTouchPosition = touch.position;
}
else if (TouchPhase.Ended == touch.phase)
hit.rigidbody.useGravity = true;
}
}
}
endPoint = objectTrans.position;
oldZ = oldZ != endPoint.z ? endPoint.z : oldZ;
}
I tried ApplyForce as I mentioned before, the ball goes up over the surface but it goes too much up, and not along with the finger… so I thought I had to do some “Swaping” when to allow gravity and when not.
I’m sorry i dont really get what kind of a scenario with pulling something around you want to get. But I can tel you how i Pulled stuff around in my app.
First wenn i got a Touchinput startet I raycast the Scene, if one of my dragableObjects get hit, I instanciate a DragerObject for the dragableObject. Now your description sounds like you want physics in, so you could attach your dragableObject with a SpringJoint to the DragerObject.
You make the DragerObject follow your touch inputposition, you could do this with a Raycast ScreenpointToRay taking the hitpoint with your plane, or get a point out of your Raydirection and the startdistance, or whatever else. Your original object follows smoothly.
I was already making calculations for the cameras equation and my surface equation to get the distances between the planes, because I realized that the Y position where Im touching is relative to the camera’s plane… :S …
So when I was moving the ball it was moving quite high.
If I understood good…
for(touch in Input.touches){
if(Input.touchCount == 1){
var r = Camera.main.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0f));
var hit : RaycastHit;
if (!Physics.Raycast(r, hit, 100f)) return;
if (hit.collider.name == "Sphere")
{
if( TouchPhase.Began == touch.phase){
print("BEGAN");
hit.rigidbody.useGravity = false;
previousTouchPosition = touch.position;
}
else if (TouchPhase.Moved == touch.phase){
...
...
this part is ok… I right? then I should create a DragableObject class and SpringJoint it to the rigidbody that returns me hit which is the sphere I want to move… this I must do in the TouchBegan. right?
Then in the touchmoved I instead of moving the sphere, I move the DragableObject… which will in consequence move the ball… am I right? Thats great idea…
Few questions…
-From there I don’t know where to position my instantiated DraggableObject, in the same place as my sphere?
-How do I get the hit point with the surface where the sphere is laying on using the Ray?
Will it work if I put the DragableObject instance on some point along the ray and then when moving the finger move the dragableObject?
Thank you very very very much for the reply.
instance to the newpoint along the ray with the same K distance I positioned initially
Gustavo
PS> If you want to understand my scenario … I attach a screenshot of the scene…
You can get the point that was clicked from the RaycastHit’s point field. The direction of the force is then obtained by subtracting the ball’s position from the hit point. Although you can just pass this straight to rigidbody.AddForce, you will find that the ball bounces backwards and forwards around the hit point rather than coming to rest. To stop this, you need to add some “damping”, which is just a reduction in force that is proportional to the speed the ball is travelling (ie, if the ball is already going fast then you don’t add much force). You can use code like the following to move the ball:-
var attractForce: float;
var damping: float;
var ray = Camera.main.ScreenPointToRay(touch.position);
var hit: RaycastHit;
...
if (Physics.Raycast(ray, hit)) {
var direction = (hit.point - ball.transform.position).normalized;
var dirSpeed = Vector3.Dot(rigidbody.velocity, direction);
ball.rigidbody.AddForce(direction * (attractForce - dirSpeed * damping));
}
...
Im trying to implement the suggestions you guys are giving me without success. if I implement what gamma suggested, I can put a object on top but then the ray will detect that object after I have place it on scene,… so the ball will not move… plus I tried with all the joints to see which one will make move the move if I move instead the prefab which is attached to the ball… but no success.
Now im trying to implement your solutoion… but damping and attractForce are 0 which then will not move the ball… :S
So to calculate the damping is to take the speed and reduce it to something less?.
What about when the ball is in repose and will move for first time? the speed will be 0 then.
I have achieved what I wanted, but in a non nice way to do it.
Here is the script, if somebody want to give it a look and maybe tell me how to improve it,
So basically I m moving 2 balls when touch.phase == TouchPhase.Moved.
The thing is that I have this JS attached to the balls in the scene, but when I touch of course both balls execute the code, so I have to put a way to identify both balls inside the same code.
so… if you would be nice and give it a check when you have a time…
Maybe I can move this code to someother component like the camera? … i dunno
Hey I screwed your code up a little bit, maybe you see what i wanted with “Instantivate a Dragger object” so your pretty independent on how many objects you want to throw around.
No idea if my code is working, i just edited yours a little bit, but it should help in understanding
If you want you can improve this new class, so the lerp works better after the touch leaves the screen and everything
Almost forgot to say, I used a hit.transform.tag, to evaluate if the hit object was your ball, if its possible giev your ball such a Tag, or you could place all balls on there own layer, and Raycast only this Layer.
Go on, I had the same problems at moving my first objects
Gamma: Thanks for the code… last week I was trying to do something similar but I failed. hehehe… anyway… so I will have tag the Sphere objects with a “Ball” Tag and add the scrip to each Sphere which in my case are only 2 isn’t it?
You can add the script to the camera or anything, you dont need multiple of these scripts on every object, for that you have the hit.transform.
With my script you will get 2 problems, the Rigidbody iskinematic und gravity yes/no is not in.
I expect it to doo curious things wenn you have 2 touch inputs and the first one ends, because then the second becomes the first, and your first spehre will “jump” to the second input.
As i said its just an example and needs some improvements