Currently I have 2 cameras, one for viewing the 3D objects (Perspective), and the other camera to view 2D objects (Orthographic).
(Also, the view of the camera never intercepts each other.)
I am trying to display a 2D object based on the position of a 3D object, like so:
What I have is the respective 2D and 3D Camera, as well as the Vector3 position of the 3D GameObject.
What I currently have:
public Vector2 Convert3DPositionTo2DPosition(Camera camera3D, Vector3 position3D, Camera camera2D) {
var tempPos = camera3D.WorldToViewportPoint(position3D);
return camera2D.ViewportToWorldPoint(tempPos);
}
The only problem is that the returned position is not completely aligned with the 3D position.
Which results in this kind of results:
Also, I have made sure that both the 3D and 2D object have their pivot point are set correctly in the center, but it still does not work as intended.
(I am currently using Unity 2019.1.14f1)
Edit
TLDR of what I want:
I want a world position that is based on an object in view of the 3D camera which is now in view of the 2D camera and have them look like they are in the same position in the player's point of view (display screen).
What I am going to instantiate in afterwards (using that position) is a non-UI GameObject.
More specifically a particle system.
Check the Viewport Rect settings for both of your Cameras!
if there is any difference between the two cameras you will always get an offset in the positions.
I tested your solution using
public Camera camera3d;
public Camera camera2d;
public Transform obj3d;
public Transform obj2d;
void Update()
{
obj2d.position = camera2d.ViewportToWorldPoint(camera3d.WorldToViewportPoint(obj3d.position));
}
and it just works fine - as long as the Viewport Rect settings match - as you can see here and here.
Related
I am looking at developing a game within Unity by using C#
The game will take the gyroscope orientation and rotate accordingly to the direction of which the phone is rotated.
I am curious of how this would work, I understand how I would be able to read and update the gyroscope orientation however I am unsure on how to assign this to a world to rotate. There will be a player on world which will be the next challenge to prevent the player clipping through the world when it is rotated.
Hence the world should rotate around the players current location.
I currently have no code as I am in the process of designing this, however i am unable to get the logic of how to make this work within my head
Thankyou
If I get your objective right, I guess rotating the camera like in a Fist-Person game should be enough, and would be way simpler than rotating the whole world while keeping the player static.
This is how I would go about it, first I wouldn't rotate the world, as that is alot of objects to rotate, but if you really wanted to you could parent all of the world to a single game object, then rotate that object about an axis based off of the players position(See this: https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html).
The simplest way is to attach your main camera to your player(Drag and drop it on your Player Object in your hierchy), then rotate your player.
for an example you can test on your machine without the gyroscrope:
using UnityEngine;
public class rotatorScript: MonoBehaviour {
void Update() {
// Will Rotate based off of left/right arrows
float rotator = -Input.GetAxisRaw("Horizontal");
// Move up or down based off of up/down Arrows
float verticalDirection = Input.GetAxisRaw("Vertical");
// Do the actual movement... using space.self so it is based on the player not the world.
transform.Translate(Vector3.up * verticalDirection * Time.deltaTime * 5f, Space.self);
transform.Rotate(0f,0f,90f * Time.deltaTime * rotator);
}
}
This script would be attached to the player.
I am trying to position my gun the way most fps games position it,
for example like this:
But I'm having a problem when I try to position and rotate it with the player. The gun doesn't rotate well and doesn't have the same position always.
Is there a way to keep a gun in the same position and make it rotate well with the player?
But my main problem is the position of the gun i need it to stay in one place like in every fps, when i start the game and pick a gun it spawn in diffrent location on the screen Because of the rotation.
Here's is the code that I am trying to use:
GameObject temp = GameObject.Find(gameObject.name);
playerGuns[keyPress] = Instantiate(temp, Player.transform.position
+ new Vector3(-2f, 3f, 4f), Quaternion.identity) as GameObject;
playerGuns[keyPress].name = gameObject.name;
playerGuns[keyPress].tag = gameObject.tag;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.rotation.SetLookRotation(Player.transform.position);
Alright here is the answer I promised:
First issue was with how you were setting your rotation, SetLookRotation takes in 2 parameters, Vector3 view, and Vector3 up the second is defaulted to Vector3.up. You were passing in the player.transform.position, for the "view" which is the direction you want transform to look in. Think of it like this, if I am far east facing west, my weapon will face east... (That is assuming the SetLookRotation normalizes it.) this is because my actual position is east, from some arbitrary origin. Something you could have used would have been player.transform.forward.
To spawn an object and have it have the same relative rotation and and position you can use Instantiate like you have in your original code. There are Several versions of instantiate.
In the comments I said to give yourself an offsetPosition and a eulerAngle, but this can be quite troublesome if you have multiple weapons. I mentioned I would give a recommendation for how I would set this up for multiple weapons... So here yea go.
Scriptable Objects,
In Unity you can create this objects to store information about a particular object, so for example a "Weapon" object can look like this:
using UnityEngine;
using System.Collections;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class WeaponObject : ScriptableObject {
public string objectName = "New Weapon";
public Vector3 offSetPosition;
public Vector3 startOffsetRotation;
public float fireRate;
// Using a gameObject to store the weapon model so you can technical
// store the firing point.
public GameObject weaponModel;
}
You can create a new object now by right-clicking in your asset directory and going to create->weapon. Once you have done this you can rename the object it made, and the inspector will show all the public fields for this object you can modify.
With this you can create multiple weapons, and store their data in like a WeaponManager, that spawns every weapon. with something like:
WeaponObject weapon = WeaponManager.getWeapon(keyPress);
playerGuns[keyPress] = Instantiate(weapon.weaponModel, Player.transform.position + weapon.offsetPosition, Quaternion.identity) as GameObject;
playerGuns[keyPress].name = weapon.objectName;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.eulerAngles = weapon.startOffsetRotation;
if(player.weaponScript != null) {
// we can have a single script for all of our weapons, and the WeaponObject
// will control its firerate, which projectiles it fires, etc.
player.weaponScript.setWeapon(weapon);
}
playerGuns[keyPress].transform.parent = Player.transform;
This line might be causing a problem. If you are parenting your gun to the players transform then it will follow the player. But it sounds like you want it to follow the camera?
try:
playerGuns[keyPress].transform.parent = Camera.main.transform;
Here is a useful answer provided by reddit user Mathias9807:
Many games will clear the depth buffer before drawing the gun model.
This will prevent the gun model from clipping through geometry but it
can look a bit weird when standing near a wall:
If you just want to render an object sticking to the camera you should
just get rid of the view matrix (Assuming you're using model-, view-
and projection matrices).
Explanation: Normally when you are using a view matrix (the camera matrix),the objects in the scene are being translated relative to the magnitude of the cameras position vector, and rotating by its yaw and pitch, which gives the illusion of a camera moving in a 3D space, but really there is no camera, just the objects in the scene that scale, and translate in in relation to the values defined for the camera.
So, when you remove that camera matrix for an object, the cameras position now has no influence on the models position, or put another way, the model does not move relative to the camera anymore but moves congruently with the camera.
I'm working on Vuforia application in Unity.
How can I make a 3D object, attached to the ImageTarget to always be vertical during the marker recognition?
So that if I will rotate the marker the model won't be upside down, but remain vertical. It should somehow "understand" were is the worlds z-axis, perhaps using sensors of the iPhone.
Here is an illustration of what I mean (grey square is a marker, a green guy is a 3D object, attached to it).
Currently if I will rotate the marker the model will also rotate:
I need to fix the rotation of the model along z-axis so that it always will remain vertical:
You can use Transfrom.LookAt () to make sure the object always camera facing, with Vector.Up as the 2nd argument:
using UnityEngine;
using System.Collections;
public class CameraFacing : MonoBehaviour
{
public Camera m_Camera;
void Update()
{
transform.LookAt(transform.position + m_Camera.transform.rotation * Vector3.forward,
m_Camera.transform.rotation * Vector3.up);
}
}
Attach this script to the image target's child (which will be shown on tracking is found). The camera is the AR camera you added in the scene.
I am generating a camera frustum mesh through code and it is working fine.
Now I am searching for a solution (shader based or else) to restrict
the camera frustum mesh if it intersects with any object. As you can see in the image, my frustum is passing through the plane which is not correct.
How can I control it? I searched and tried to apply different kinds of shaders but nothing seems to work.
Get the frustum planes of the camera.
Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(Camera.main); //Or whatever camera you are using
For each GameObject in the scene, get its Renderer component's bounds if any.
Renderer renderer = GetComponent<Renderer>();
if (renderer != null)
{
//get renderer.bounds
}
Test if the renderers bounds intersect with any of the frustum planes.
bool canSee = GeometryUtility.TestPlanesAABB(frustumPlanes, renderer.bounds);
if (canSee)
{
//do something
}
This should be a pretty good approximation of whether your camera can "see" the mesh (i.e if the frustum intersects with any object)
I have made a thing in unity2d where an object moves according to the location of the mouse compared to the location of the object, to do this there is a vector going from the object to the mouse, all movement is either parrallel to this or perpendicular to it.
This worked fine before adding rotation of the sprite (added as shown below)
void RoterModMus()
{
fRotationIGrader = Vector2.Angle (Vector2.up, vVectorToMouse.normalized);
if(vVectorToMouse.normalized.x<0)
{
transform.rotation =Quaternion.Euler(0, 0, fRotationIGrader);
}
else{transform.rotation =Quaternion.Euler(0, 0, -fRotationIGrader); }
}
When i stop running this funtion in update the movement works again.
Is there a way to either rotate the sprite without rotating the object, or to make this not hurt movement??
I havn't been able to find anything on any of those questions, and i cant figure it out (sorry for danish code)
The code checks the angle between up and the mouse (up is zero in unity) and sets the rotation of the object to that or minus that
Awwkaw
One solution is to add an empty gameObject with the sprite component as a child to your object and then rotate the child AKA empty gameObject with sprite.