I need to move a cube by clicking and dragging in C# Unity3D. My code currently creates the cubes by cilcking a button.
using UnityEngine;
using System.Collections;
public class CDraggable : MonoBehaviour
{
Texture btnimg;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
Update ()
{
//here to write mousedrag code.
}
void OnGUI()
{
if (GUI.Button(new Rect(400, 250, 50, 50), btnimg))
{
//Debug.Log("Clicked the button with an image");
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = new Vector3(-0.7F, 2, 0);
}
}
}
Add the script DragRigidbody.js to your camera. It is included in unity's default assets at StandardAssets/Scripts/GeneralScripts/, and it does exactly what you want.
This might help you.. :)
Vector2 screenPoint = Vector2.Zero ;
void OnMouseDown()
{
screenPoint = Camera.main.WorldToScreenPoint(scanPos);
offset = scanPos - Camera.main.ScreenToWorldPoint(
new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
Vector3 curScreenPoint = Vector3.Zero;
Vector3 curPosition = Vector3.Zero;
void OnMouseDrag()
{
curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
transform.position = curPosition;
}
Maybe this will help if your game is 2D, I think.
void Update{
if (Input.GetMouseButton())
{
transform.position = Input.mousePosition;
}
}
Related
I have a ball that move forward and bounce and rotate, and I want the camera to follow it and rotate with it so the camera always look at the ball from behind. So I made the script bellow but the camera didn't look at the ball when rotating!
NB: I didn't use camera as a child of the ball because I don't want the camera to bounce.
Camera Script:
public Transform Ball;
private Vector3 Offset;
// Use this for initialization
void Start () {
Offset = transform.position - Ball.transform.position;
}
// Update is called once per frame
void LateUpdate () {
transform.position = new Vector3(Ball.transform.position.x + Offset.x, transform.position.y, Ball.transform.position.z + Offset.z);
transform.rotation = Ball.transform.rotation;
}
[SerializeField]
private Transform target;
[SerializeField]
private Vector3 offsetPosition;
[SerializeField]
private Space offsetPositionSpace = Space.Self;
[SerializeField]
private bool lookAt = true;
private void Update()
{
Refresh();
}
public void Refresh()
{
if(target == null)
{
Debug.LogWarning("Missing target ref !", this);
return;
}
// compute position
if(offsetPositionSpace == Space.Self)
{
transform.position = target.TransformPoint(offsetPosition);
}
else
{
transform.position = target.position + offsetPosition;
}
// compute rotation
if(lookAt)
{
transform.LookAt(target);
}
else
{
transform.rotation = target.rotation;
}
}
The target is your player gameobject
I want to:
move a particular object in its own X- axis to and from, by using mouse.
Clamp the movement between that box gap
Code i tried but not working for me:
void Update()
{
point = Camera.main.ScreenToWorldPoint(
new Vector3(Input.mousePosition.x,
(transform.position.y-Camera.main.transform.position.y),
(transform.position.z-Camera.main.transform.position.z)));
point.y = transform.position.y;
point.z = transform.position.z;
transform.position = point;
}
To clamp a value you can use the Mathf.Clamp() method.
The full solution could look something like this:
Add a script to your lever object:
using UnityEngine;
using UnityEngine.EventSystems;
public class MoveOnMouseDrag : MonoBehaviour {
public float halfDistance;
void Start()
{
EventTrigger trigger = GetComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Drag;
entry.callback.AddListener((data) => { OnDragDelegate((PointerEventData)data); });
trigger.triggers.Add(entry);
}
public void OnDragDelegate(PointerEventData data)
{
float distanceFromCamera = Vector3.Distance(Camera.main.transform.position, transform.position);
var newPos = Camera.main.ScreenToWorldPoint(new Vector3(data.position.x, data.position.y, distanceFromCamera));
transform.position = new Vector3(Mathf.Clamp(newPos.x, -halfDistance, halfDistance),
transform.position.y,
transform.position.z);
}
}
In order for the script to work you have to add EventTrigger component to the same object, EventSystem to the scene and PhysicsRaycaster component to the camera.
I have this code to drag and drop 3d objects on a world:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpyAI : MonoBehaviour {
Animator anim;
private Vector3 screenPoint;
private Vector3 offset;
// Use this for initialization
void Start () {
anim = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
}
void OnMouseDown()
{
anim.SetBool("drag", true);
screenPoint = Camera.main.WorldToScreenPoint(transform.position);
offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
transform.position = curPosition;
}
void OnMouseUp()
{
anim.SetBool("drag", false);
anim.SetBool("idle", true);
}
}
The problem is:
When im dragging the object, sometimes, depending on the mouse movement it goes undergound
How can I make the object to stay above the ground while dragging it?
The most obvious thing that should change is the z-value of curScreenPoint. Using the docs as reference, it should probably be:
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane);
Now for maybe a bit more fine-tuned behavior, you might want to make the object raise up above the ground if the ground has slopes or something with complex colliders on it like a chair or table. To do this, you likely want to do a sphere cast down towards the ground from a point somewhat above what's calculated in curPosition. Use the hitInfo to see how far down it goes, and adjust the y position of curPosition accordingly.
Created new script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mouseDrag : MonoBehaviour
{
float distance = 10;
void OnMouseDrag()
{
Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance);
Vector3 objPosition = Camera.main.ScreenToWorldPoint(mousePosition);
transform.position = objPosition;
}
}
Then in another script in the Start function i'm creating 4 cubes and add the mouseDrag to each cube. But when running and clicking and dragging nothing happen. I'm not getting any errors or exceptions.
void Start()
{
lp = gameObjectToRaise.transform.localPosition;
ls = gameObjectToRaise.transform.localScale;
List<GameObject> cubes = new List<GameObject>();
GameObject cube = Cube.CreatePrimitive(Cube.CubePivotPoint.UPLEFT);
GameObject cube1 = Cube.CreatePrimitive(Cube.CubePivotPoint.UPRIGHT);
GameObject cube2 = Cube.CreatePrimitive(Cube.CubePivotPoint.BACKUP);
GameObject cube3 = Cube.CreatePrimitive(Cube.CubePivotPoint.UPRIGHT);
cubes.Add(cube);
cubes.Add(cube1);
cubes.Add(cube2);
cubes.Add(cube3);
cube.GetComponentInChildren<Renderer>().material.color = Color.blue;
cube1.GetComponentInChildren<Renderer>().material.color = Color.red;
cube2.GetComponentInChildren<Renderer>().material.color = Color.green;
cube3.GetComponentInChildren<Renderer>().material.color = Color.yellow;
cube.transform.position = new Vector3(lp.x, lp.y, lp.z - 0.5f);
cube1.transform.position = new Vector3(lp.x, lp.y, lp.z);
cube2.transform.position = new Vector3(lp.x, lp.y, lp.z + 5);
cube3.transform.position = new Vector3(lp.x + 5, lp.y, lp.z);
cube1.transform.Rotate(0, 90, 0);
cube3.transform.Rotate(0, 90, 0);
StartCoroutine(scaleCube(cube.transform));
StartCoroutine(scaleCube(cube1.transform));
StartCoroutine(scaleCube(cube2.transform));
StartCoroutine(scaleCube(cube3.transform));
foreach (GameObject go in cubes)
{
go.AddComponent<mouseDrag>();
}
}
IEnumerator scaleCube(Transform trans)
{
while (raiseAmount < raiseTotal)
{
raiseAmount += 1f;
trans.localScale += new Vector3(speed * Time.deltaTime, speed * Time.deltaTime, 0);
yield return null;
}
}
}
I just tried now with a single cube gameobject i added for testing it
and it's working fine. But when i'm using the cubes using the CUBE
class helper it's not working.
In this case, the mouseDrag script should be attached to the child cube(not the CubeHolder object).After that, you should be moving the parent of the cube which is "CubeHolder".
If you ever move the child cube, you will break the pivot point.
Simply change
transform.position = objPosition;
to
transform.parent.position = objPosition;
then attach the mouseDrag script to the child cube not the "CubeHolder".
Maybe the problem is that it's attaching the script to the
parentObject "CubeHolder" and not to the created cubes ?
Yes. OnMouseDrag will only be called if attached to an Object with a Collider and the child cube is the only object with the Collider. The parent object is only there to be used as a pivot point feature.
NOTE:
You should not use OnMouseDrag for this. You should be dragging the cube/Object with the new UI event. There are many of the callback functions listed in this answer.
The script below is something you should be using. Attach the CubeDrag sctipt to the child cube then change everything that says transform.position to transform.parent.position.
using UnityEngine;
using UnityEngine.EventSystems;
public class CubeDrag: MonoBehaviour, IPointerDownHandler, IDragHandler, IEndDragHandler
{
Camera mainCamera;
float zAxis = 0;
Vector3 clickOffset = Vector3.zero;
// Use this for initialization
void Start()
{
addEventSystem();
zAxis = transform.position.z;
}
public void OnPointerDown(PointerEventData eventData)
{
Vector3 tempPos = eventData.position;
tempPos.z = Vector3.Distance(transform.position, Camera.main.transform.position);
clickOffset = transform.position - mainCamera.ScreenToWorldPoint(tempPos);
Debug.Log("Mouse Down");
}
public void OnDrag(PointerEventData eventData)
{
Vector3 tempPos = eventData.position;
tempPos.z = Vector3.Distance(transform.position, Camera.main.transform.position);
Vector3 tempVec = mainCamera.ScreenToWorldPoint(tempPos) + clickOffset;
tempVec.z = zAxis;
transform.position = tempVec;
Debug.Log("Dragging Cube");
}
public void OnEndDrag(PointerEventData eventData)
{
}
void addEventSystem()
{
mainCamera = Camera.main;
if (mainCamera.GetComponent<PhysicsRaycaster>() == null)
mainCamera.gameObject.AddComponent<PhysicsRaycaster>();
EventSystem eveSys = GameObject.FindObjectOfType(typeof(EventSystem)) as EventSystem;
if (eveSys == null)
{
GameObject tempObj = new GameObject("EventSystem");
eveSys = tempObj.AddComponent<EventSystem>();
}
StandaloneInputModule stdIM = GameObject.FindObjectOfType(typeof(StandaloneInputModule)) as StandaloneInputModule;
if (stdIM == null)
stdIM = eveSys.gameObject.AddComponent<StandaloneInputModule>();
}
}
I am trying to make a dragging effect. I have a project where u are supposed to pull a bone out of meat. The dragging is working, but when i grab the bone i can move it in all directions. What i would like to achieve is that i can only drag it in one direction. On the images below i mean the red line. I tried many things but nothing worked so far. Any help is appreciated.
I used these functions for the dragging.
void OnMouseDown()
{
offset = this.transform.position - Camera.main.ScreenToWorldPoint(new Vector2(Input.mousePosition.x, Input.mousePosition.y));
}
void OnMouseDrag()
{
Vector3 curScreenPoint = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
transform.position = curPosition;
}
Just get the x component of your mouse and use localPosition:
void OnMouseDown()
{
offset = this.transform.localPosition - Camera.main.ScreenToWorldPoint(new Vector2(transform.localPosition.x, Input.mousePosition.y));
}
void OnMouseDrag()
{
Vector3 curScreenPoint = new Vector2(transform.localPosition.x, Input.mousePosition.y);
Vector3 mousePos = Camera.main.ScreenToWorldPoint(curScreenPoint);
Vector3 curPosition = new Vector3(mousePos.x, 0f, 0f) + offset;
transform.localPosition = curPosition;
}