I've created an architectural app and I want the client to be able to lift up the roof off the building. I have a script that allows me to drag the roof all over the screen in the X & Y axis: using UnityEngine; using System.Collections; public class mouseDrag_y_axis : MonoBehaviour { void OnMouseDrag() { Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 6.33f); // Vector3 objPosition = Camera.main.ScreenToWorldPoint(mousePosition); transform.position = objPosition; } } It works but what I really want is that the roof can be lifted up on the Y Axis alone. Looking on Google yealed nothing with regards to just moving the object on just the Y-Axis. It must be very straightforward to do but my skill is 3D animation, not coding. So how can I do this, (there's some free 3d modeling in it for anyone that can keep me from tearing out my hair further!) Thanks.
Insert Code (csharp): objPosition.x = transform.position.x; objPosition.z = transform.position.z; right before you assign this result to transform.position at the end of that method.
Works like a charm. Thanks a million mate. Let me know if you need anything modeled and if I can it's done. Cheers.
I realise now that the roof object when clicked moves in relation to where the camera is. No doubt because of this line here: Code (CSharp): Vector3 objPosition = Camera.main.ScreenToWorldPoint(mousePosition); So how do I make it that the cube will move up and down without it having anything to do with where the camera is located. The app is AR based so where the camera is when the roof object is clicked is in all different positions and I see as a result, the roof instantly disappears when clicked. Thanks again.
Right. You don't want to instantly move the roof to where a line through the camera crosses the view plane; you want to move the roof up and down as the mouse moves up and down. Try something like this. Code (CSharp): using UnityEngine; using System.Collections; public class mouseDrag_y_axis : MonoBehaviour { public float dragSpeed = 1f; Vector3 lastMousePos; void OnMouseDown() { lastMousePos = Input.mousePosition; } void OnMouseDrag() { Vector3 delta = Input.mousePosition - lastMousePos; Vector3 pos = transform.position; pos.y += delta.y * dragSpeed; transform.position = pos; lastMousePos = Input.mousePosition; } }
Works great, thanks. Anyway to change the sensitivity? I tried to change to dragSpeed but it didn't make any difference.
Erm... hmm. That's exactly what dragSpeed is for. We're multiplying that by the mouse delta, so it's hard to see why it wouldn't make any difference. Perhaps you didn't change it enough?
How can I stop when object collides with other collider? I'll continue dragging but object has collided with other collider and further does not moves. How can I do this? Thx
hii Joe, I used your script for dragging to Y axis the gameobject how can I limit the drag like when it hit an endpoint upwards you wont be able to drag it upwards same thing when downwards.. need help.. using UnityEngine; using System.Collections; public class mouseDrag_y_axis : MonoBehaviour { public float dragSpeed = 1f; Vector3 lastMousePos; void OnMouseDown() { lastMousePos = Input.mousePosition; } void OnMouseDrag() { Vector3 delta = Input.mousePosition - lastMousePos; Vector3 pos = transform.position; pos.y += delta.y * dragSpeed; transform.position = pos; lastMousePos = Input.mousePosition; } }
You could do this with a couple of if statements, but an even easier way is to use the Mathf.Clamp function. So it'd look like this: Code (CSharp): using UnityEngine; using System.Collections; public class mouseDrag_y_axis : MonoBehaviour { public float dragSpeed = 1f; public float minY = -5; public float maxY = 10; Vector3 lastMousePos; void OnMouseDown() { lastMousePos = Input.mousePosition; } void OnMouseDrag() { Vector3 delta = Input.mousePosition - lastMousePos; Vector3 pos = transform.position; pos.y += delta.y * dragSpeed; pos.y = Mathf.Clamp(pos.y, minY, maxY); transform.position = pos; lastMousePos = Input.mousePosition; } } This is simple but maybe not quite ideal, because if you drag quite a ways past the limit, and then drag back in the other direction, the object immediately starts moving — you might instead want it to wait until the mouse has crossed the limit point again. That's certainly doable too; let me know if you want to see that version.
when I first tap the gameobject it goes down automatically without dragging it and one last thing how can I make may player when standing above the gameObject and start dragging it upwards it also drags my player upwards.. really appreciate your help
Well, that's a bit trickier. Are you using Physics? (I.e., do the thing you're dragging, and the player, both have a Rigidbody component?)
Hi, Im having a problem dunno what is happening I set the position just like the first picture but when I touch the cube without starting dragging this happens on second pic.. the limit endpoint not working .. Can I see the if condition for limit?
No, those are the minimum and maximum Y values you want to allow. The code does not let the Y position of the object ever be less than minY, or greater than maxY. So you need to set those correctly for the valid range of Y values.
aside from dragging it to Y axis how can I make it drag to Z and X axis at the same time.. thank you so much your response is a big help for me
Well I'm not even sure what that means. You can only move the mouse in 2 dimensions; how exactly do you want this to change the position of the object in 3 dimensions? If you can define that clearly, you can probably code it. You just need some more lines like lines 16-17, that affect the other parts of pos.
I got this script to be able to drag my player with the platform but when the player walk inside the platform and tried to walk outside the platform it doesnt work it just stays inside the platform private GameObject target = null; private Vector3 offset; void Start() { target = null; } void OnTriggerEnter (Collider col) { target = col.gameObject; offset = target.transform.position - transform.position; } void OnTriggerExit (Collider col) { target = null; } void LateUpdate() { if (target != null) { target.transform.position = transform.position + offset; } }
Please use code tags when posting code. It's the button in the toolbar that looks like this: It makes the code much easier to read. So it looks like you're not using physics. That's a reasonable choice! Just be sure to be consistent about it, and don't use rigidbodies to move things elsewhere, or you'll get into some trouble. Now the script above basically says, "when something enters my trigger, then keep that thing pinned to me, at its original relative position, until it exits." It's a pretty clever solution, except that it has the problem you mentioned: the pinned thing can't exit once it enters. (It also can't work with more than one object at a time.) Perhaps you want something like this version, which applies a delta movement to all targets whenever it moves. This is untested code, right out of my head, so you might need to debug it a little bit. Code (CSharp): private List<Transform> targets = new List<Transform>(); private Vector3 lastPos; void Start() { lastPos = transform.position; } void OnTriggerEnter (Collider col) { targets.Add(col.transform); } void OnTriggerExit (Collider col) { targets.Remove(col.transform); } void LateUpdate() { Vector3 delta = transform.position - lastPos; if (delta != Vector3.zero) { foreach (var target in targets) { target.position += delta; } } lastPos = transform.position; }
it looks like it doesn't lift my player properly along with the platform. it lift a little bit and then start to sink from the platform just like the image
Are you using physics on your player? How does your player move around? What you're describing sounds like wrestling with the physics engine to me.
I used Touch To Move for movement of my Player. It has a Rigidbody and NavMesh component. Code (CSharp): void StartMoving() { if (StopWalking) { return; } Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); RaycastHit hit; if (Input.GetMouseButtonUp (0)) { if (Physics.Raycast (ray, out hit, 100)) { NavMeshHit navmeshHit; int walkableMask = 1 << NavMesh.GetAreaFromName("Walkable"); if (NavMesh.SamplePosition (hit.point, out navmeshHit, 1.0f, walkableMask)) { agent.SetDestination (navmeshHit.position); } if (hit.collider.CompareTag("Obstacle")) { CanMove = false; Debug.Log("Obstacle"); } if (hit.collider.CompareTag("Gate")) { CanMove = false; Debug.Log("Gate"); } } }
Ah, so that's it. You're not only using physics, you're using NavMesh movement too! I don't know how to make it properly stick to the platform in this case. In fact, I'm not sure it's even valid to use a NavMesh when your geometry is changing — my understanding is that these are static (I've never used Unity's navmesh stuff myself). So I think you may be out of luck with that combination.
Hey, thank you very much for your answers, they have helped me a lot. However, if you have some free time it would help me even more if you could put the script you are talking about at the end of this answer. Thank you very much.