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>();
}
}
Related
I am new to game developing, and I am building a game with an orthographic camera,
the camera suppose to be following the player and when I click and drag the mouse it supposes to turn around him.
I managed to make the camera turn around the player, but when I add the code for the mouse drag when I hold the mouse it turns but when I release it slides.
This is my C# code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerFollow : MonoBehaviour {
public Transform PlayerTransform;
private Vector3 _cameraOffset;
[Range(0.01f, 1.0f)]
[SerializeField] float SmoothFactor = 0.5f;
[SerializeField] bool LookAtPlayer = false;
[SerializeField] bool RotateAroundPlayer = true;
[SerializeField] float RotationsSpeed = 5.0f;
// Use this for initialization
void Start () {
_cameraOffset = transform.position - PlayerTransform.position;
}
void LateUpdate () {
if (Input.GetMouseButtonDown(0))
{
RotateAroundPlayer = true;
}
else if (Input.GetMouseButtonUp(0))
{
RotateAroundPlayer = false;
}
if (RotateAroundPlayer)
{
Quaternion camTurnAngle =
Quaternion.AngleAxis(Input.GetAxis("Mouse X") * RotationsSpeed, Vector3.up);
_cameraOffset = camTurnAngle * _cameraOffset;
}
Vector3 newPos = PlayerTransform.position + _cameraOffset;
transform.position = Vector3.Slerp(transform.position, newPos, SmoothFactor);
if (LookAtPlayer || RotateAroundPlayer)
transform.LookAt(PlayerTransform);
}
}
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 am trying to place a sphere on a ground plane and on a button click remove the sphere and place a cube.
This is the script attached to the AR camera object.
using UnityEngine;
using Vuforia;
using System.Collections;
public class ModelSwapper : MonoBehaviour {
public AnchorStageBehaviour theTrackable;
public Transform myModelPrefab;
private bool mSwapModel = false;
// Use this for initialization
void Start () {
Transform myModelTrf = GameObject.Instantiate(myModelPrefab) as Transform;
myModelTrf.parent = theTrackable.transform;
myModelTrf.localPosition = new Vector3(0f, 0f, 0f);
myModelTrf.localRotation = Quaternion.identity;
myModelTrf.localScale = new Vector3(0.05f, 0.05f, 0.05f);
myModelTrf.gameObject.active = true;
}
// Update is called once per frame
void Update () {
if (mSwapModel && theTrackable != null) {
SwapModel();
mSwapModel = false;
}
}
void OnGUI() {
if (GUI.Button (new Rect(50,50,120,40), "Swap Model")) {
mSwapModel = true;
}
}
private void SwapModel() {
GameObject trackableGameObject = theTrackable.gameObject;
//disable any pre-existing augmentation
for (int i = 0; i < trackableGameObject.transform.GetChildCount(); i++)
{
Transform child = trackableGameObject.transform.GetChild(i);
child.gameObject.active = false;
}
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
// Re-parent the cube as child of the trackable gameObject
cube.transform.parent = theTrackable.transform;
// Adjust the position and scale
// so that it fits nicely on the target
cube.transform.localPosition = new Vector3(0, 0.2f, 0);
cube.transform.localRotation = Quaternion.identity;
cube.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
// Make sure it is active
cube.active = true;
}
}
But instead, it spawns multiple cubes along with the sphere.
Multiple clones
Since, there isn't much documentation or anything else on Vuforia ground plane, it's hard to get things done. Why is this behaving strange?
You could avoid the Update and it should fix your issue, replace these two methods in your script with the following:
void Update () {
}
void OnGUI() {
if (GUI.Button (new Rect(50,50,120,40), "Swap Model")) {
if(theTrackable)
{
SwapModel();
}
}
}
And then only to right and only to up and only down.
The main idea is to scale to one direction.
The problem is i'm not using the editor to add new empty gameobject or a cube.
I'm using a script to create a cube and a new empty gameobject.
In the editor in the scene window i have a cube already. And in the script i'm using this cube to create/duplicate another cube and creating new empty gameobject.
I tried to work like the answer here: The solution method 2.
Solution
But this solution is using the editor and i'm using a script.
What i tried so far:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Test : MonoBehaviour
{
public GameObject gameObjectToRaise;
public float raiseAmount;
public float raiseTotal = 50;
public float speed = 2;
public static bool raised = false;
public int x, z;
private List<GameObject> cubes;
private GameObject go;
public bool randomColor;
public Color[] colorChoices;
Vector3 lp;
Vector3 ls;
// Use this for initialization
void Start()
{
lp = gameObjectToRaise.transform.localPosition;
ls = gameObjectToRaise.transform.localScale;
go = new GameObject();
CreateCubes();
}
void Update()
{
if (DetectPlayer.touched == true)
{
if (raiseAmount < raiseTotal)
{
float raiseThisFrame = speed * Time.deltaTime;
if (raiseAmount + raiseThisFrame > raiseTotal)
{
raiseThisFrame = raiseTotal - raiseAmount;
}
raiseAmount += raiseThisFrame;
gameObjectToRaise.transform.localScale += new Vector3(raiseThisFrame, raiseThisFrame, 0);
go.transform.localScale += new Vector3(raiseThisFrame, raiseThisFrame, 0);
go.transform.position += Vector3.left * (speed / 2) * Time.deltaTime;
}
else
{
raised = true;
}
}
}
private List<GameObject> CreateCubes()
{
cubes = new List<GameObject>();
for (int a = 0; a < x; a++)
{
for (int b = 0; b < z; b++)
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
if (randomColor)
{
cube.GetComponent<Renderer>().material.color = colorChoices[Random.Range(0, (colorChoices.Length))];
}
cube.transform.position = new Vector3(lp.x - 1, lp.y, lp.z);
cube.transform.Rotate(0, 90, 0);
cubes.Add(cube);
}
}
go.transform.position = new Vector3(lp.x - 2,lp.y,lp.z);
go.transform.Rotate(0, 90, 0);
cubes[0].transform.parent = go.transform;
return cubes;
}
}
But again it's scaling the go var(New empty gameobject) on both sided left and right and i want only to the left.
In my first question it was marked as already answered but the solution in the link is when using the editor and i want to do it by script.
In my first question it was marked as already answered but the
solution in the link is when using the editor and i want to do it
by script.
It is still the-same solution. Create a cube then create an empty GameObject. Position that empty GameObject to the left side of the cube. Now make that cube a child a of that GameObject with childCube.transform.SetParent(thatObject.transform);. That's it.
Below is a helper class to do this. It can position the pivot point to any position. I provided CubePivotPoint enum to make it even easier. You can also pass in Vector3 position as a pivot point.
public class CUBE
{
public enum CubePivotPoint
{
MIDDLE, LEFT, RIGHT, UP, DOWN, FORWARD, BACK
}
//Takes CubePivotPoint Enum as pivot point
public static GameObject CreatePrimitive(CubePivotPoint pivot)
{
//Calculate pivot point
Vector3 cubePivot = createPivotPos(pivot);
//Create cube with the calculated pivot point
return createCubeWithPivotPoint(cubePivot);
}
//Takes Vector3 as pivot point
public static GameObject CreatePrimitive(Vector3 pivot)
{
//Create cube with the calculated pivot point
return createCubeWithPivotPoint(pivot);
}
private static Vector3 createPivotPos(CubePivotPoint pivot)
{
switch (pivot)
{
case CubePivotPoint.MIDDLE:
return new Vector3(0f, 0f, 0f);
case CubePivotPoint.LEFT:
return new Vector3(-0.5f, 0f, 0f);
case CubePivotPoint.RIGHT:
return new Vector3(0.5f, 0f, 0f);
case CubePivotPoint.UP:
return new Vector3(0f, 0.5f, 0f);
case CubePivotPoint.DOWN:
return new Vector3(0f, -0.5f, 0f);
case CubePivotPoint.FORWARD:
return new Vector3(0f, 0f, 0.5f);
case CubePivotPoint.BACK:
return new Vector3(0f, 0f, -0.5f);
default:
return default(Vector3);
}
}
private static GameObject createCubeWithPivotPoint(Vector3 pivot)
{
//Create a cube postioned at 0,0,0
GameObject childCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
//Create an empty parent object
GameObject parentObject = new GameObject("CubeHolder");
//Move the parent object to the provided pivot postion
parentObject.transform.position = pivot;
//Make the childcube to be child child of the empty object (CubeHolder)
childCube.transform.SetParent(parentObject.transform);
return parentObject;
}
}
Usage:
void Start()
{
GameObject cube = CUBE.CreatePrimitive(CUBE.CubePivotPoint.RIGHT);
StartCoroutine(scaleCube(cube.transform));
}
IEnumerator scaleCube(Transform trans)
{
while (true)
{
trans.localScale += new Vector3(0.1f, 0, 0);
yield return null;
}
}
As for integrating this into your current code, change
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
to
GameObject cube = CUBE.CreatePrimitive(CUBE.CubePivotPoint.RIGHT);.
then change cube.GetComponent<Renderer>() to cube.GetComponentInChildren<Renderer>() since the cube is now a child Object of another GameObject.
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;
}
}