Lock camera position in VR - c#

I'm playing around with VR a bit, so far I can move a character around and such. However the position of the camera is changing. I want my camera to be in a fixed position and only be able to change up/down position and the normal rotation with the HMD.
void Start ()
{
startPos = transform.localPosition;
parentObj = transform.root;
}
void Update()
{
ResetVR();
}
void ResetVR()
{
if (parentObj != null)
{
startPos -= InputTracking.GetLocalPosition(VRNode.CenterEye);
transform.localRotation = Quaternion.Inverse(parentObj.localRotation);
}
}
With this my character rotates normally but the camera won't stay in a fixed position.
For example, if I rotate 90 degrees, the camera ends up left of the character. I want the camera stay in a fixed position.

You only want to up/down. This is the-same as rotating around x-axis only. Get the original position. Convert the Quaternion to angle then rotate with transform.localEulerAngles instead of transform.localRotation.Overwrite the other two axis(y,z) with originalPos variables before rotating. You may need to modify this to get it working properly.
Transform parentObj;
Vector3 startPos;
Vector3 originalPos;
void Start()
{
startPos = transform.localPosition;
originalPos = transform.localPosition;
parentObj = transform.root;
}
void Update()
{
ResetVR();
}
void ResetVR()
{
if (parentObj != null)
{
startPos -= InputTracking.GetLocalPosition(VRNode.CenterEye);
Quaternion tempRot = Quaternion.Inverse(parentObj.localRotation);
Vector3 newAngle = tempRot.eulerAngles;
transform.localEulerAngles = new Vector3(newAngle.x, originalPos.y, originalPos.z);
}
}

You might want to have a look at this rule.
See Unity's documentation about this.

Related

How to make a smooth crosshair in Unity3D?

In Unity 3D I'd like to create a crosshair for my top-down 2D-shooter that gradually moves to its target whenever the player has the same x-position as the target.
The problem is that I want a smooth animation when the crosshair moves to the target. I have included a small gif from another game that shows a crosshair I'd like to achieve. Have a look at it:
Crosshair video
I tried to do that with the following script but failed - the crosshair jumps forth and back when the enemies appear. It doesn't look so smooth like in the video I mentioned above.
The following script is attached to the player:
[SerializeField]
private GameObject crosshairGO;
[SerializeField]
private float speedCrosshair = 100.0f;
private Rigidbody2D crosshairRB;
private bool crosshairBegin = true;
void Start () {
crosshairRB = crosshairGO.GetComponent<Rigidbody2D>();
crosshairBegin = true;
}
void FixedUpdate() {
//Cast a ray straight up from the player
float _size = 12f;
Vector2 _direction = this.transform.up;
RaycastHit2D _hit = Physics2D.Raycast(this.transform.position, _direction, _size);
if (_hit.collider != null && _hit.collider.tag == "EnemyShipTag") {
// We touched something!
Debug.Log("we touched the enemy");
Vector2 _direction2 = (_hit.collider.gameObject.transform.position - crosshairGO.transform.position).normalized;
crosshairRB.velocity = new Vector2(this.transform.position.x, _direction2.y * speedCrosshair);
crosshairBegin = false;
} else {
// Nothing hit
Debug.Log("nothing hit");
crosshairRB.velocity = Vector2.zero;
Vector2 _pos2 = new Vector2(this.transform.position.x, 4.5f);
if (crosshairBegin) crosshairGO.transform.position = _pos2;
}
}
I think you need create a new variable call Speed translation
with
speed = distance from cross hair to enemy position / time (here is Time.fixedDeltaTime);
then multiply speed with velocity, the cross hair will move to enmey positsion in one frame.
but you can adjust speed by mitiply it with some float > 0 and < 1;

How to move the camera up the Y axis only when the player reaches the top 1/2 of the screen in Unity C#

This is for a 2D platform game.
I don't want the camera to move up the Y axis when the player jumps. I only want it to move when the player to the upper part of the screen so it can scroll up to vertical platforms and ladders.
Does anybody know what to enter in the code and the Unity editor so that can be done?
Here's the code I have so far in the camera script.
public class CameraControl : MonoBehaviour {
public GameObject target;
public float followAhead;
public float smoothing;
private Vector3 targetPosition;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
targetPosition = new Vector3 (target.transform.position.x, transform.position.y, transform.position.z);
if (target.transform.localScale.x > 0f) {
targetPosition = new Vector3 (targetPosition.x + followAhead, targetPosition.y, targetPosition.z);
} else {
targetPosition = new Vector3 (targetPosition.x - followAhead, targetPosition.y, targetPosition.z);
}
transform.position = Vector3.Lerp (transform.position, targetPosition, smoothing * Time.deltaTime);
}
}
I guess you have a bool tied to the jump which triggers the jumping animation.
So, in the Update() of the camera you can do something like this:
void Update() {
// Update camera X position
if (isPlayerJumping) return;
// Update camera Y position
}
This way, you update the Y position of the camera only if the player isn't jumping, while still updating the X position in all cases (even while jumping).

Move the camera only until a certain position

https://scontent.fmgf1-2.fna.fbcdn.net/v/t34.0-12/15870843_1543174992374352_1359602831_n.gif?oh=dc048c9e04617007c5e82379fd5a9c1a&oe=586CC623
Can you see the blue area in this gif? I want block the camera when the player go more to left, to not see the blue area. This is the code that I'm using to move the camera:
public class configuracoesDaCamera : MonoBehaviour {
Vector3 hit_position = Vector3.zero;
Vector3 current_position = Vector3.zero;
Vector3 camera_position = Vector3.zero;
float z = 0.0f;
public static bool bDedoNoHud;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
hit_position = Input.mousePosition;
camera_position = transform.position;
}
if (Input.GetMouseButton(0))
{
current_position = Input.mousePosition;
LeftMouseDrag();
}
Debug.Log("bDedoNoHud" + bDedoNoHud);
}
void LeftMouseDrag()
{
if (!bDedoNoHud)
{
// From the Unity3D docs: "The z position is in world units from the camera." In my case I'm using the y-axis as height
// with my camera facing back down the y-axis. You can ignore this when the camera is orthograhic.
current_position.z = hit_position.z = camera_position.y;
// Get direction of movement. (Note: Don't normalize, the magnitude of change is going to be Vector3.Distance(current_position-hit_position)
// anyways.
Vector3 direction = Camera.main.ScreenToWorldPoint(current_position) - Camera.main.ScreenToWorldPoint(hit_position);
// Invert direction to that terrain appears to move with the mouse.
direction = direction * -1;
Vector3 position = camera_position + direction;
transform.position = position;
}
}
}
You mean setting up boundaries?
This should help you
Put it in the update()

C# How to make a smooth jump in unity3d without moving the X, towards the nearest object

I would like to make a smooth jump towards the nearest cube. I already have a script to detect the closest cube. I want that the X-axis is locked, so only the Y-axis and the Z-axis change when jumping. I would like to use a Jump animation when jumping. I already tried to use Vector3MoveTowards, but that didn't really work well, maybe I didn't use it properly.
Detect nearest cube where the player should jump to (C#)
void Update()
{
FindClosestCube ();
GameObject closestCube = FindClosestCube ();
Debug.Log (closestCube);
}
GameObject FindClosestCube() {
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag("cube");
GameObject closest = null;
float distance = Mathf.Infinity;
float position = transform.position.z;
foreach (GameObject go in gos) {
float diff = go.transform.position.z - position;
float curDistance = diff;
if (curDistance < distance) {
closest = go;
distance = curDistance;
}
}
return closest;
}
The tricky part is that at some cubes you have to jump up (y+1), with some cubes you jump towards the same Y (y+0) and with some cubes you jump down (y-1).
How do I do this?
Image of how it looks like:
EDIT: I have this code right now:
----------------C#-----------------
Rigidbody rb;
public int clicks = 0;
Vector3 target;
public Animation jumpAnimation;
bool jump = false;
float cubeDiffY;
bool movePlayer;
public float smoothTime = 0.3f;
public float yVelocity = 0.0f;
void Start()
{
rb = GetComponent<Rigidbody> ();
}
void Update ()
{
FindClosestCube ();
GameObject closestCube = FindClosestCube ();
Debug.Log ("Closestcube = " + closestCube);
target = closestCube.transform.position + new Vector3 (0f, 0.7f, 0f);
cubeDiffY = target.y - transform.position.y;
movePlayer = true;
Debug.Log("Cube Difference Y-axis = " + Mathf.Round(cubeDiffY));
if (Input.GetMouseButtonDown (0))
{
clicks += 1;
jump = true;
jumpAnimation = gameObject.GetComponent<Animation>();
//jumpAnimation.Play ();
}
if (jump == true)
{
Jump ();
}
}
void Jump()
{
float newPosition = Mathf.SmoothDamp (transform.position.y, target.y, ref yVelocity, smoothTime);
transform.position = new Vector3 (0, newPosition, transform.position.z);
}
I calculated the difference in Y-axis between the cube where the player is standing on and the closestCube. But the Jump() doesn't work. How do I fix that?
Okay I set up a quick version of your game and got what you wanted to work, it is not exactly a quick solution, because what your doing doesn't have built in functionality for other than using animations.
Here is the character script that has all the code you need and commented thoroughly so it should explain itself.
using UnityEngine;
public class Character : MonoBehaviour
{
//the collider for the player
private new BoxCollider collider;
//the jump box collider on a empty game object that is a child to the player object
public BoxCollider JumpBox;
//the offset of the cube so it doesn't stop inside of it
public Vector3 cubeOffset;
//how high the jump will be
public float JumpHeight;
//how fast the jump will be
public float JumpSpeed;
//holds the change in position the jump will produce
private Vector3 jumpDelta;
//holds the destination cube the jump is attempting to hit
private Cube destinationCube;
//true if a jumping animation is currently playing
private bool jumping = false;
//used to swap the jump direction from up to down
private bool jumpDirection = true;
//used to hold the position of the jump so it knows when to stop
private float jumpPosition = 0;
// Use this for initialization
void Start()
{
collider = GetComponent<BoxCollider>();
}
// Update is called once per frame
void Update()
{
if(jumping)
{
//move straight towards the cube
transform.position = transform.position + (JumpSpeed * jumpDelta);
//move up and down to simulate a jump
//check the current move direction
if (jumpDirection)
{
//add to the jump position twice product of the JumpHeight the JumpSpeed so that it will
//rise and fall the same amount of time it takes to move to the destination
jumpPosition += JumpHeight * JumpSpeed * 2;
//if it has passed the jump height reverse the jump direction
if (jumpPosition >= JumpHeight)
jumpDirection = !jumpDirection;
transform.position += transform.up * JumpHeight * JumpSpeed * 2;
}
//the jump direction is going down
else
{
jumpPosition -= JumpHeight * JumpSpeed * 2;
transform.position -= transform.up * JumpHeight * JumpSpeed * 2;
}
//check if the character collider intersects witht he cubes collider
//if it has then stop jumping and set the final position as the destination position
if (collider.bounds.Intersects(destinationCube.BoxCollider.bounds))
{
jumping = false;
transform.position = destinationCube.transform.position + cubeOffset;
}
}
//detect a jump
if (Input.GetKeyDown(KeyCode.Space))
{
//detect all hits on the jump box
Collider[] hits = Physics.OverlapBox(JumpBox.center, JumpBox.size * 0.5f);
//get the closest collider with the right tag
Collider result = GetClosestColliderWithTag(hits, "Cube");
//if we have a result then begin the jumping animation
if(result != null)
{
//gets the destination cubes cube component(the custom class you have on your cubes)
destinationCube = result.gameObject.GetComponent<Cube>();
//calculate the jump delta
jumpDelta = (result.transform.position + cubeOffset) - transform.position;
//remove the left and right components so the jumping doesnt move to the left or right of the player
Vector3 component = Vector3.Project(jumpDelta, -transform.right);
jumpDelta -= component;
component = Vector3.Project(jumpDelta, transform.right);
jumpDelta -= component;
//setup the jump animation control fields to the initial values
jumpPosition = 0;
jumpDirection = true;
jumping = true;
}
}
}
private Collider GetClosestColliderWithTag(Collider[] colliders, string tag)
{
//just gets the closest collider
float distance = float.MaxValue;
int result = -1;
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].tag == tag)
{
float distanceTemp = Vector3.Distance(transform.position, colliders[i].transform.position);
if (distanceTemp < distance)
{
distance = distanceTemp;
result = i;
}
}
}
if (result != -1)
return colliders[result];
else return null;
}
}
And here is my cube script which has some things you will need to add
using UnityEngine;
public class Cube : MonoBehaviour {
//these arent important just fields I used to set up a quick version of your game
public GameObject StartPoint;
public GameObject EndPoint;
public float Speed;
private Vector3 directionVector;
private bool direction;
//YOU WILL NEED THIS!!
[HideInInspector]
public BoxCollider BoxCollider;
// Use this for initialization
void Start() {
//not important
directionVector = EndPoint.transform.position - StartPoint.transform.position;
directionVector.Normalize();
//DONT FORGET TO SET YOUR BOX COLLIDER
BoxCollider = GetComponent<BoxCollider>();
}
// Update is called once per frame
void Update()
{
float distance = 0;
if (direction)
{
distance = Vector3.Distance(EndPoint.transform.position, transform.position);
transform.position += directionVector * Speed;
if (distance < Vector3.Distance(EndPoint.transform.position, transform.position))
direction = !direction;
}
else
{
distance = Vector3.Distance(StartPoint.transform.position, transform.position);
transform.position -= directionVector * Speed;
if (distance < Vector3.Distance(StartPoint.transform.position, transform.position))
direction = !direction;
}
}
}
Previous Answer
I would say you need to calculate the perceived position of the object in the future.
Vector3 futurePos = cubePos + (cubeMoveDirection * cubeMoveSpeed);
Once you have the future position, even if it is not exact, you should aim your animation towards that position. To do this I would have the animation change a speed vector instead of an actual transforms position that way we can rotate this speed vector in any direction you want while keeping the orientation of the block. Otherwise you have to rotate the entire block to point towards the direction you want. If this is what you want then put your block under a empty gameobject, rotate the empty gameobject to point to where you want and do the speed calculations only.
Next your animation should have a net move vector which should be pre-calculated and scaled down or up to meet the distance to the future position. It will look something like this(note this is not tested)
//class fields
Vector3 AnimatedSpeed;
Vector3 AnimationDelta;
//basic calculation
//get the direction vector from the players current position to the future
block position
Vector3 dirVector = futurePos - transform.position;
//find the rotation from the current orientation to the direction vector
Quaternion rotation = Quaternion.FromToRotation(transform.forward, dirVector);
//calculate the distance from you to the cube and scale it with the magnitude of the AnimationDelta
float result = Vector3.Distance(transform.position, futurePos);
result = result / animationDelta.magnitude;
//finally rotate the forward vector by the rotation and multiply it by the
//animation speed and the result to get the step by step movement as
//the animation plays. NOTE: The animation should be based on forward direction
transform.position += (AnimationSpeed * rotation) * result * Time.deltaTime;
Hopefully this does it, like I said I haven't tested it at all so you may have to do some tweaking based on your particular case as this is essentially psuedo-code.
Good luck! I'm off to bed I'll check back when I wake up.

Unity3D NavMashAgent not moving -C# Code

I don't know this is a right place to ask this. Because this is a Game development ralated question. I post this question in here (gamedev.stackexchange.com -https://gamedev.stackexchange.com/questions/109190/navmashagent-not-moving) but still no responce. And also post thin in Unity forum (http://answers.unity3d.com/questions/1075904/navmashagent-not-moving-in-unity3d-5.html). Any one here to help me.
Ill post my question here again
Im trying to move a Cube to CheckPoints. FindClosestTarget() method gives closest Checkpoint. When Cube hit the CheckPoint, ChackPoint will be Set as Inactive. When the Collision happens FindClosestTarget() call again and get the new closest CheckPoint. Thing is Cube not moving. It Look at the closest check point but not moving.
using UnityEngine;
using System.Collections;
public class EnimyAI03N : MonoBehaviour {
NavMeshAgent agent;
Transform Target;
private float rotationSpeed=15.0f;
void Start () {
agent = GetComponent<NavMeshAgent>();
Target = FindClosestTarget ().transform;
}
void Update ()
{
LookAt (Target);
MoveTo (Target);
}
// Turn to face the player.
void LookAt (Transform T){
// Rotate to look at player.
Quaternion rotation= Quaternion.LookRotation(T.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime*rotationSpeed);
//transform.LookAt(Target); alternate way to track player replaces both lines above.
}
void MoveTo (Transform T){
agent.SetDestination(T.position);
}
void OnCollisionEnter (Collision col)
{
if(col.gameObject.name.Contains("CheckPoint"))
{
Target = FindClosestTarget ().transform;
}
}
GameObject FindClosestTarget() {
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag("CheckPoint");
GameObject closest=null;
float distance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject go in gos) {
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = go;
distance = curDistance;
}
}
return closest;
}
}
Make sure the SetActive(false); is happening before you search for the new target, by just putting both lines in the same area.
void OnCollisionEnter (Collision col)
{
if(col.gameObject.name.Contains("CheckPoint"))
{
col.gameObject.SetActive(false);
Target = FindClosestTarget ().transform;
}
}

Categories