Multiple clones of model spawning in target (Vuforia and Unity) - c#

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();
}
}
}

Related

Unity 3D Spring joint textures

Hello i'm doing a simple 3d game and wanted to make something like a grappling hook and it all works perfectly, but i can't find a solution how to make it to have a texture. Here's my code:
SpringJoint joint;
public GameObject playerCam;
Vector3 grapplepoint;
private void StartGrapplinghook()
{
print("grapple");
RaycastHit[] hits = Physics.RaycastAll(playerCam.transform.position, playerCam.transform.forward, 30f);
if (hits.Length < 1) return;
grapplepoint = hits[0].point;
joint = gameObject.AddComponent<SpringJoint>();
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = grapplepoint;
joint.spring = 2.5f;
joint.damper = 0.25f;
}
Hope you guys can help me.
I would use a LineRenderer for this, and update its positions every frame if it's enabled.
Make and configure a LineRenderer component on the same gameobject the script is on. Explanation for code in comments.
[RequireComponent(typeof(LineRenderer))]
public class MyClassName : MonoBehaviour
{
[SerializeField]
LineRenderer grappleRenderer;
SpringJoint joint;
public GameObject playerCam;
Vector3 grapplepoint;
void Awake()
{
// Whatever is already here...
// If you don't need a fresh grapple copy every time,
// create them once here or in the editor and re-use them
joint = gameObject.AddComponent<SpringJoint>();
joint.autoConfigureConnectedAnchor = false;
joint.spring = 2.5f;
joint.damper = 0.25f;
grappleRenderer = GetComponent<LineRenderer>();
grappleRenderer.positionCount = 2; // this could just be set in the inspector
// Don't use the grapple by default
joint.enabled = false;
grappleRenderer.enabled = false;
}
private void StartGrapplinghook()
{
print("grapple");
RaycastHit[] hits = Physics.RaycastAll(playerCam.transform.position,
playerCam.transform.forward, 30f);
if (hits.Length < 1) return;
grapplepoint = hits[0].point;
joint.enabled = true;
joint.connectedAnchor = grapplepoint;
grappleRenderer.enabled = true;
}
void StopGrapplingHook()
{
// turn off joint and renderer
joint.enabled = false;
grappleRenderer.enabled = false;
}
// grapple rendering can happen after all other updates finish
// determining if it should be rendered or not that frame
void LateUpdate()
{
if (grappleRenderer.enabled)
{
Vector3 grappleStart = transform.position; // or something that makes sense
grappleRenderer.SetPoints(new Vector3[]{grapplepoint, grappleStart});
}
}
}

2d Platformer game stone changing size

I am trying to make a platformer game. In the platformer game has a moving platform that makes everything it touches its transform's child while it touches it. Interestingly, whenever a stone(A movable object with a rigidbody and a polygon collider) touches the moving platform, the stone's scale goes haywire. Even though the scale reads the same on the transform component, it appears to be larger or smaller than it really is when touching it. When it stops touching the platform, the stone appears normal. Can anyone help me. Thank you.
This is the moving platform script that moves the platform around.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveTwoTransforms : MonoBehaviour
{
public Transform pointA;
public Transform pointB;
public bool HasReachedA;
public bool HasReacedB;
// Start is called before the first frame update
void Start()
{
transform.position = pointA.position;
HasReacedB = true;
HasReachedA = false;
StartCoroutine(GlideAround());
}
// Update is called once per frame
void Update()
{
}
public IEnumerator GlideAround()
{
while (true)
{
while (HasReachedA == false)
{
yield return new WaitForEndOfFrame();
transform.position = Vector2.Lerp(transform.position, pointA.position, 0.01f);
if ((Mathf.Abs(Vector2.Distance(pointA.position, transform.position)) < 0.01f))
{
HasReacedB = false;
HasReachedA = true;
}
}
while (HasReacedB == false)
{
yield return new WaitForEndOfFrame();
transform.position = Vector2.Lerp(transform.position, pointB.position, 0.01f);
if ((Mathf.Abs(Vector2.Distance(pointB.position, transform.position)) < 0.01f))
{
HasReacedB = true;
HasReachedA = false;
}
}
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if((collision.gameObject.tag == "Stone"|| collision.gameObject.tag == "Player") && (collision.transform.position.y - collision.transform.lossyScale.y / 2 >= transform.position.y))
{
collision.transform.parent = transform;
}
}
private void OnCollisionExit2D(Collision2D collision)
{
collision.transform.parent = null;
}
}
This is the stone script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RememberPositions : MonoBehaviour
{
public Vector3 StartingPosition;
public Vector3 StartingRotation;
public Vector3 StartingScale;
float StartRotation;
// Start is called before the first frame update
void Start()
{
StartingPosition = new Vector3(transform.position.x, transform.position.y, 0);
StartingRotation = new Vector3(0, 0, transform.position.z);
StartingScale = new Vector3(transform.localScale.x, transform.localScale.y, transform.localScale.z);
}
// Update is called once per frame
void Update()
{
transform.localScale = StartingScale;
}
}
There are no errors whatsoever and the rigidbody seems to be changing to the shape of the stone. Can anyone please specify the correct code I should use? Thank you.
If your moving platform is scaled, your stone will get scaled too. There are workarounds shown here to avoid this issue. One of them is adding a child GameObject to the platform, and moving the collision handling from the platform to that child.

How can i click and drag a gameobject with the mouse?

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>();
}
}

How can i scale a cube to only one direction left?

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.

Unable to instantiate a Behavior in Unity

I am rather new (very new, in-fact less than 8 hrs new) to Unity 3D.
As it turns out, my newness to Unity has posed me with a rather weird problem. Consider two Behaviors below:
Behavior CamCaptureDialogBehavior:
using UnityEngine;
using System.Collections;
public class CamCaptureDialogBehavior : MonoBehaviour
{
// 200x300 px window will apear in the center of the screen.
private Rect windowRect = new Rect ((Screen.width - 200) / 2, (Screen.height - 300) / 2, 200, 300);
// Only show it if needed.
private bool show = false;
public CamCaptureDialogBehavior ()
{
}
// Use this for initialization
void Start ()
{
}
void OnGUI ()
{
if (show)
windowRect = GUI.Window (0, windowRect, DialogWindow, "Game Over");
}
void DialogWindow (int windowID)
{
float y = 20;
GUI.Label (new Rect (5, y, windowRect.width, 20), "Title goes here");
if (GUI.Button (new Rect (5, y, windowRect.width - 10, 20), "Ok")) {
Application.LoadLevel (0);
show = false;
}
}
// To open the dialogue from outside of the script.
public void Open ()
{
show = true;
}
// Update is called once per frame
void Update ()
{
}
}
Behavior: PictureButtonBehavior:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class PictureButtonBehavior : MonoBehaviour
{
private bool displayedGUI = false;
private bool ShowThisGUI = false;
void Start ()
{
}
void Update ()
{
if (displayedGUI == true) {
Debug.Log (string.Format ("displayedGUI = {0}\r\n", displayedGUI));
displayedGUI = false;
ShowThisGUI = false;
}
}
void OnGUI ()
{
if (ShowThisGUI) {
Debug.Log (string.Format ("ShowThisGUI = {0}\r\n", ShowThisGUI));
displayedGUI = true;
ShowThisGUI = false;
CamCaptureDialogBehavior ccdb = new CamCaptureDialogBehavior ();
if (ccdb != null) {
ccdb.enabled = true;
ccdb.Open ();
}
}
}
public void OnClick ()
{
ShowThisGUI = true;
}
}
At CamCaptureDialogBehavior ccdb = new CamCaptureDialogBehavior ();, ccdb is always null.
Is there a unqiue way to instantiate classes in Unity/Mono?
or, How can I instantiate CamCaptureDialogBehavior in PictureButtonBehavior and be able to display the dialog represented by CamCaptureDialogBehavior.
You can't call new on MonoBehaviours.
You can instantiate prefabs that have the script attached to them.
GameObject g = Instantiate(prefab) as GameObject;
Or you can add them to an already existing GameObject.
gameObject.AddComponent<ScriptName>();
Next you will ask what is a prefab. It is something very simple, yet very powerful in Unity. Short tutorial on how to make one.
You can create a prefab by selecting Asset > Create Prefab and then
dragging an object from the scene onto the “empty” prefab asset that
appears. Simply dragging the prefab asset from the project view to the
scene view will then create instances of the prefab.

Categories