I am using Vuforia and Unity3D to develop an application. For this, I need to get the camera position (x,y,z) in real world unit from an image target while tracking the image with a mobile phone. I was wondering if it is possible to get such position information in Vuforia . if Yes, any sample code would be highly appreciated.
Try something like this.
public class ExampleClass : MonoBehaviour {
public Transform target;
Camera camera;
void Start() {
camera = GetComponent<Camera>();
}
void Update() {
Vector3 screenPos = camera.WorldToScreenPoint(target.position);
Debug.Log("target is " + screenPos.x + " pixels from the left");
}
}
What this does is
Transforms position from world space into screen space.
Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.
May not be exactly what you want but its a starting point.
EDIT:
This returns world Space not local space so this should be exactly what you want
public class ExampleClass : MonoBehaviour {
public GameObject someObject;
public Vector3 thePosition;
void Start() {
// Instantiate an object to the right of the current object
thePosition = transform.TransformPoint(Vector3.right * 2);
Instantiate(someObject, thePosition, someObject.transform.rotation);
}
}
Note that the returned position is affected by scale. Use Transform.TransformDirection if you are dealing with direction vectors. You can perform the opposite conversion, from world to local space using Transform.InverseTransformPoint.
Related
I published a game named Rotate Ball Pro last week. But some people told me that playing the game was not so comfortable.
I used unity and C# for coding. My game levels has labyrinths and a sphere on it. The sphere has rigidbody component but the labyrinths have not. So you can control the labyrinth by tilting the phone and thus the sphere can roll. But you must hold the phone parallel to the ground to keep the labyrinth balanced. For example you can not play by lying on back or holding the phone with any angle. So this makes playing uncomfortable.
I want to to keep the labyrinth balanced in whatever the rotation of the phone is when the game starts. I searched web and tried many things but could not solve it. Can anyone help me?
Here is the explanation of the problem with an image: Problem
Here is the direct game link: Rotate Ball Pro
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class NewMovementScript : MonoBehaviour
{
public float multiplier = 0;
void Start()
{
Input.gyro.enabled = true;
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
void FixedUpdate()
{
var dir = Vector3.zero;
dir.x = Input.acceleration.x * -1 * multiplier;
dir.y = Input.acceleration.z * multiplier;
dir.z = Input.acceleration.y * multiplier;
transform.eulerAngles = new Vector3(dir.z, 0f, dir.x);
}
}
Input.acceleration is the position change between the last and current frame and as you noted already doesn't take the initial state into account.
This also is barely related to rotations at all.
I think for your usage you would rather simply use Input.gyro.attitude!
Example from the docs
public class Example : MonoBehaviour
{
// Rotate the object to match the device's orientation
// in space.
void Update()
{
transform.rotation = Input.gyro.attitude;
}
}
If your object uses a rigidbody you might want to rather use
public class Example : MonoBehaviour
{
private Rigidbody rigidbody;
void Awake ()
{
rigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
rigidbody.MoveRotation(Input.gyro.attitude);
}
}
I'm doing a simple game to get started with unity, there's a cube who goes straight and dodge other cubes (obstacles) which are spawned randomly. To make the obstacle always spawn in front of the player I set up a code that makes the 7 spawn position (the blocks get generated in them randomly) follow the player's coordinates but adding 100 to the Z so they get generated not upside the player. Now, my problem is that when generated the obstacle also changes their X position, making them fall from the platform when I go to the right or to the left with the player. How can I make they follow only the Z position of the player and not the X?
Here is the code that makes the spawners change position:
public class MoveSpawn : MonoBehaviour
{
public Transform player;
public Vector3 offset;
// Update is called once per frame
void Update()
{
transform.position = player.position + offset;
}
}
I would simply multiply the player's position by (0,0,1) (in other words, Vector3.forward) before adding it to the offset:
public class MoveSpawn : MonoBehaviour
{
public Transform player;
public Vector3 offset;
// Update is called once per frame
void Update()
{
transform.position = player.position * Vector3.forward + offset;
}
}
Oh, that's pretty easy.
So if you only want to look at the Z(or any other) coordinates of the Cube or any object in Unity you can simply use:
transform.position.z
That's the same thing you would do with vectors. Something like that:
Vector3 offset = ...;
Debug.Log(offset.x) //returns x coordinate of offset
Good day, I'm making a 2D platformer game and I'm trying to make to cam follow the player. But ignore the y-axis so when the player jumps the cam stays in positions instead of following the player.
Example (see asset pack demo): https://ansimuz.itch.io/gothicvania-church-pack
How can I do this using Cinemachine?
You don't have to override the camera's Y value in your camera controller script. This would be a very basic implementation:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
public GameObject player; //Public variable to store a reference to the player game object
public bool followY = false;
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start ()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate ()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
if(followY)
{
transform.position = player.transform.position + offset; // we should follow the player Y movements, so we copy the entire position vector
}
else
{
transform.position = new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z) + offset; // we just copy the X and Z values
}
}
}
Attach this script to the camera and you can enable or disable the Y-axis movement by setting the boolean accordingly. In case you will never need this functionality, just keep the line in the else block.
I hope this will help you!
I've spent my whole day trying to figure out a problem I'm having with my school project, so I'm off to my last resort: stackoverflow!
My problem:
I'm trying to rotate a character relative to a Camera you can rotate around the character.
input: xbox controller
relevant information:
The camera rotates horizontally around the character, using the right joystick
The character movement happens with the left joystick
The character already moves relative to the Camera, that's working as expected. I'm trying to rotate the character, which happens in a seperate method.
When the left joystick is pulled downwards, the character should always be facing (and moving towards) the camera.
When the left joystick is pulled upwards, the character should always be facing the opposite of (and moving away from) the camera.
I'm leaving a lot of code out, just to keep it readable for you guys. If you need something, just ask and I'll provide.
What I have so far: https://imgur.com/TERUXV6
Why it's wrong: The character rotation is perfect. However, I'm cheating here. The camera rotates according to the world coordinates. As soon as I rotate the camera, this is obvious.
The following script is attached to the Character GameObject.
public class CharacterBehaviour : MonoBehaviour
{
public GameObject HumanoidModel;
[SerializeField]private Transform _mainCameraTransform;
private void Update()
{
ApplyMovement();
RotateCharacter();
}
private void ApplyMovement()
{
//get input movement vector
Vector3 inputMovement = new Vector3(_inputMoveCharacterXAxis, 0, _inputMoveCharacterZAxis);
//make sure camera forward is player movement forward
Vector3 mainCameraForwardXz = Vector3.Scale(_mainCameraTransform.forward, new Vector3(1, 0, 1)); //multiplied by (1, 0, 1) to remove Y component
Vector3 mainCameraRightXz = Vector3.Scale(_mainCameraTransform.right, new Vector3(1, 0, 1)); //multiplied by (1, 0, 1) to remove Y component
Vector3 movementInCameraForwardDirection = mainCameraForwardXz * inputMovement.z;
Vector3 movementInCameraRightDirection = mainCameraRightXz * inputMovement.x;
Vector3 movementForward = movementInCameraForwardDirection + movementInCameraRightDirection;
_velocity = movementForward * MaximumSpeed;
}
private void RotateCharacter()
{
Vector3 inputDirection = new Vector3(_inputMoveCharacterXAxis, 0, _inputMoveCharacterZAxis);
HumanoidModel.transform.LookAt(HumanoidModel.transform.position +
HumanoidModel.transform.forward + inputDirection);
}
The following script is attached to the Main Camera GameObject
public class CameraBehaviour : MonoBehaviour
{
[SerializeField] private Transform _characterTransform;
[SerializeField] private Transform _mainCameraTransform;
private void Update ()
{
RotateCamera();
}
// Rotate camera horizontally
private void RotateCamera()
{
_mainCameraTransform.RotateAround(_characterTransform.position, Vector3.up, _inputRotateCameraHorizontal);
}
}
The source of the problem is in the RotateCharacter() function. I know I need to get some calculations in there to make the character rotation relative to the camera rotation, I just can't figure out what that calculation is, and why.
Thanks in advance!
Thrindil
so heres what you need...
camDefault, a Vector3 for the cameras initial position behind the char.
camCur, a Vector3 for the cameras current position(to track where it is in orbit around the character)
you need to set camDefault in Awake() to the its current position at that time, IE camDefault = cam.transform.position);
then in a fixed update,
camCur= cam.transform.position;
then,
if(Input//your horizontal axis here//==0){
if(camCur!=camDefault){
//translate camera to cam default
cam.tranform.translate(camDefault);
cam.lookat(player.transform.forward);
}
}
keep in mind that some of this is pseudocode, just a general direction. but the unity methods are there. if properly implemented this script will allow you to rotate around your char with right stick, than the camera will slide back behind you when you let go.
I believe, for your sanity, it would be easier to make the camera a direct child of ybot, so it rotates with it and you dont need to do it maually the camera will always stay behind the player. but thats just my opinion. as it sits now, the camera, and the model are children of player, if you want the camera to turn with the player, just make it a child of that model.
in this case, you could store the initial rotation, and current rotation as above, and us your stick to look left and right and then snap back to forward when you let the stick go.
What i'm trying to do is, i have a player say a lion, and there are enemies, other animals.
What i want is the player to grab the enemy when they die and put the neck in his mouth, so he can take them with him.
All enemy animals have a localposition for the neck but they are all different.
What i have is this:
Enemy1.SetParent(DragMouth.transform);
Enemy1.gameObject.transform.position = Enemy1.GetComponentInChildren<Neck>().transform.TransformPoint(0,0,0);
Enemy1.localRotation = Quaternion.identity;
This kinda works but because all animals have different positions it doesn't work good.
What would be the correct way to set the neck of the enemies to the "Dragmouth" position?
I'm using unity btw.
You can add a script to the animals that knows the offset from their own position to the position of their neck. Then when the enemy tries to grab the target you just substract that offset to the base mouth position to keep them in the correct position.
So something like (NOTE The example code will only work without rotation adjustments, you'll have to do some more calculations to make it work with rotations :)):
public class Lion : Monobehaviour
{
public Vector3 offsetToMouth
{
get {
return mouthObject.localPosition;
}
}
//Make a child object that is on the mouth position
//Reference to this object through unity inspector
public Transform mouthObject;
//The target that is currently in lions mouth
private Target currentTarget;
void Update()
{
var mouthPosition = transform.position + offsetToMouth;
var newPosition = mouthPosition - currentTarget.offsetToNeck;
currentTarget.gameObject.transform.position = newPosition;
}
}
public class Target : Monobehaviour
{
public Vector3 offsetToNeck
{
get {
return neckObject.localPosition;
}
}
//Make a child object that is on the neck position
//Reference to this object through unity inspector
public Transform neckObject;
}