I'm coming across a roadblock on something I thought would be a relatively simple problem. I want to "roll" the camera on the z-axis by pressing the "Q" and "E" keys.
Here is the code I've written, which is attached to my camera object:
#pragma strict
var keyboardSensitivity : float = 10.0f;
private var rotZ : float;
private var localRotation : Quaternion;
function Start () {
rotZ = 0.0f;
}
function Update () {
if(Input.GetKey(KeyCode.Q)) {
rotZ += Time.deltaTime * keyboardSensitivity;
localRotation = Quaternion.Euler(0.0f, 0.0f, rotZ);
transform.rotation = localRotation;
}
if(Input.GetKey(KeyCode.E)) {
rotZ -= Time.deltaTime * keyboardSensitivity;
localRotation = Quaternion.Euler(0.0f, 0.0f, rotZ);
transform.rotation = localRotation;
}
}
Based on my knowledge, this should be all that is needed. But when I hit the Q or E keys, absolutely nothing happens. Why?
Nothing happens because your code is likely not attached to the camera or it is attached to another GameObject. It cannot be attached to another GameObject. It has to be attached to the camera since you are referencing transform.rotation which will affect the current GameObject the script is attached to.
Select your camera then drag the script to it. Click "Play" and press the Q or E button. The camera should rotate. I really do recommend Unity project tutorials to you.
Related
I use rigidbody.MovePosition to move around my character , and have a camera following it. The problem is when i switch directions suddenly the player will teleport a bit instead of smoothly moving in the opposite direction of motion. The scripts for the player and Camera are set to FixedUpdate , if I try moving camera to a LateUpdate then the whole thing jitters a lot.
Player Script :
private void Start()
{
m_Rb = GetComponent<Rigidbody>();
m_InputAxisName = "Vertical" + m_playerNumber;
m_StrafeAxisName = "Horizontal" + m_playerNumber;
}
private void FixedUpdate()
{
m_InputAxisValue = Input.GetAxis(m_InputAxisName);
m_StrafeAxisValue = Input.GetAxis(m_StrafeAxisName);
//Movement
Vector3 movement = (transform.forward * m_InputAxisValue * m_Speed * Time.deltaTime) + (transform.right * m_StrafeAxisValue * m_Speed * Time.deltaTime);
m_Rb.MovePosition(m_Rb.position + movement);
}
Camera Script
void FixedUpdate () {
m_NewPos = m_player.transform.position + m_offset;
if (m_Rotate)
{
Quaternion newRot = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * m_rotSpeed, Vector3.up);
m_offset = newRot * m_offset;
}
transform.position = Vector3.SmoothDamp(transform.position, m_NewPos, ref m_MoveSpeed, m_DampTime); ;
if (m_Rotate)
transform.LookAt(m_player);
}
the problem is that your motion logic is implemented within FixedUpdate but you take the time.deltaTime. You have to use the fixedDeltaTime version.
Also do not try to get the Input within the FixedUpdate that can also cause jitter and stutter/jumping of objects.
Instead get the Input from Update and use variables to pass it inside the FixedUpdate.
A last one, look at your RigidBody for the Interpolation/Extrapolation depending on your Scene Setup and Camera this could also help.
I finally figured out what was wrong with it, something about the rotation of the camera in the fixed update. I moved it to update and it works fine now
In my scenario, I have a table (plane) that a ball will roll around on using nothing but physics giving the illusion that the mobile device is the table using Input.gyro.attitude. Taking it one step further, I would like this relative to the device origin at the time Start() is called, so if it is not being held in front of a face or flat on the table, but just relative to where it started, and may even be reset when the ball is reset. So the question is, is how do I get the difference between the current attitude and the origin attitude, then convert the X and Z(?) difference into a Vector3 to AddForce() to my ball object whilst capping the max rotation at about 30 degrees? I've looked into a lot of Gyro based input manager scripts and nothing really helps me understand the mystery of Quaternions.
I could use the relative rotation to rotate the table itself, but then I am dealing with the problem of rotating the camera along the same rotation, but also following the ball at a relative height but now with a tilted offset.
AddForce() works well for my purposes with Input.GetAxis in the Editor, just trying to transition it to the device without using a Joystick style UI controller.
Edit: The following code is working, but I don't have the right angles/euler to give the right direction. The game is played in Landscape Left/Right only, so I should only need a pitch and yaw axis (imagine the phone flat on a table), but not roll (rotated around the camera/screen). I may eventually answer my own question through trial and error, which I am sure is what most programmers do.... XD
Started on the right track through this answer:
Answer 434096
private Gyroscope m_Gyro;
private speedForce = 3.0f;
private Rigidbody rb;
private void Start() {
m_Gyro = Input.gyro;
m_Gyro.enabled = true;
rb = GetComponent<Rigidbody>();
}
private Vector3 GetGyroForces() {
Vector3 resultantForce = Vector3.zero;
//Quaternion deviceRotation = new Quaternion(0.5f, 0.5f, -0.5f, -0.5f) * m_Gyro.attitude * new Quaternion(0,1,0,0);
float xForce = GetAngleByDeviceAxis(Vector3.up);
float zForce = GetAngleByDeviceAxis(Vector3.right);
//float zForce = diffRot.z;
resultantForce = new Vector3(xForce, 0, zForce);
return resultantForce;
}
private float GetAngleByDeviceAxis(Vector3 axis) {
Quaternion currentRotation = m_Gyro.attitude;
Quaternion eliminationOfOthers = Quaternion.Inverse(Quaternion.FromToRotation(axis, currentRotation * axis));
Vector3 filteredEuler = (eliminationOfOthers * currentRotation).eulerAngles;
float result = filteredEuler.z;
if (axis == Vector3.up) {
result = filteredEuler.y;
}
if (axis == Vector3.right) {
result = (filteredEuler.y > 90 && filteredEuler.y < 270) ? 180 - filteredEuler.x : filteredEuler.x;
}
return result;
}
void FixedUpdate() {
#if UNITY_EDITOR
rb.AddForce(new Vector3(Input.GetHorizontal * speedForce, 0, Input.GetVertical * speedForce));
#endif
#if UNITY_ANDROID
rb.AddForce(GetGyroForces);
#endif
}
I am following the space shooter tutorial on Unity website.
I have completed upto movement actions of the player object.
When I start my game, the spaceship automatomatically moves to the upper left corner even when no input is given.
I have followed the tutorial exactly as it is. Even the completed scene that is available in the Asset Store is having the same problem.
I am using Unity 5.3.
PlayerController.cs
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
public float xMin, xMax, zMin, zMax;
}
public class PlayerController : MonoBehaviour {
public float speed;
public Boundary boundary;
public float tilt;
// Use this for initialization
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
GetComponent<Rigidbody>().velocity = movement * speed;
GetComponent<Rigidbody>().position = new Vector3(
Mathf.Clamp(GetComponent<Rigidbody>().position.x,boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp(GetComponent<Rigidbody>().position.z, boundary.zMin, boundary.zMax));
GetComponent<Rigidbody>().rotation = Quaternion.Euler(0,0, GetComponent<Rigidbody>().velocity.x * -tilt);
}
}
Your code seems correct and since you say that the demo scene does the same, I suppose that the problem comes from your Axis input: The lines taht add movement
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Uses the Axes called Horizontal and Vertical. It is possible that on your instance of unity, these input are linked to a device that sends events (you maybe have a controller plugged...)
To test this, You can add the following line below reading the input:
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Debug.Log("Movement: " + moveHorizontal + ", " + moveVertical); // <-- add this
This will write the values you get as input. If you don't touch anything, they should be zero. If they are not zero, Go to Edit -> Project Settings -> Input, You will see how your keyboard, mouse and other controllers are linked to events in Unity such as Horizontal and Vertical
See http://docs.unity3d.com/Manual/class-InputManager.html for more info on Input Manager
Good luck!
I've applied this standard assets script to my camera for a 2D game and it's actually doing a good job but since my background texture is placed inside a quad that "follows" the player and not the camera at higher movement speed the camera gets too far or too much behind the player and gets out of view.
Since I never programmed in JS I'd like to ask you how should I tweak this code to stop the script from moving the camera if the velocity is over (for example) 5f.
I tried to change it this way :
var target : Transform;
var smoothTime = 0.3;
private var thisTransform : Transform;
private var velocity : Vector2;
function Start()
{
thisTransform = transform;
}
function Update()
{
if(velocity.x > 5f) //in C# I'd do it this way, but apparently
velocity.x = 5f; //this is not stopping the camera from getting out of game-sight
thisTransform.position.x = Mathf.SmoothDamp( thisTransform.position.x,
target.position.x, velocity.x, smoothTime);
thisTransform.position.y = Mathf.SmoothDamp( thisTransform.position.y,
target.position.y, velocity.y, smoothTime);
}
This possibly happens because i'm actually passing a reference as a parameter (velocity.x called as a reference http://docs.unity3d.com/Documentation/ScriptReference/Mathf.SmoothDamp.html)
I am not sure if I understand you correctly.
If you want to set your camera's max speed, Mathf.SmoothDamp() can set maxSpeed.
var maxSpeed : float = 5.0f;
Mathf.SmoothDamp(transform.position.x, target.position.x, velocity.x, smoothTime, maxSpeed);
I am making a game in Unity 3D from scratch.
i am getting an error
UnassignedReferenceException: The variable bullitPrefab of 'MoveAround' has not been assigned.
You probably need to assign the bullitPrefab variable of the MoveAround script in the inspector.
UnityEngine.Object.Internal_InstantiateSingle (UnityEngine.Object data, Vector3 pos, Quaternion rot) (at C:/BuildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/Editor/UnityEngineObject.cs:44)
UnityEngine.Object.Instantiate (UnityEngine.Object original, Vector3 position, Quaternion rotation) (at C:/BuildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/Editor/UnityEngineObject.cs:53)
MoveAround.Update () (at Assets/MoveAround.js:22)
i am getting an error in the following code
enter code here
var speed = 3.0;
var rotateSpeed = 3.0;
var bullitPrefab:Transform;
function Update ()
{
var controller : CharacterController = GetComponent(CharacterController);
//Rotate around y - axis
transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0);
//Move forward / bacward
var forward = transform.TransformDirection(Vector3.forward);
var curSpeed = speed * Input.GetAxis("Vertical");
controller.SimpleMove(forward * curSpeed);
if(Input.GetButtonDown("Jump"))
{
var bullit = Instantiate(bullitPrefab, gameObject.Find("spwanPoint").transform.position, Quaternion.identity);
}
}
#script RequireComponent(CharacterController)
here is the link of the tutorial
http://www.youtube.com/watch?v=wfpZ7_aFoko&list=PL11F87EB39F84E292
When you attach the script to an object in Unity3d, you should see the public vars in the object explorer. Make sure you drag the bullitPrefab to that script, so Unity3d knows which prefab to use in bullitPrefab. It now says (None), but it should be bullitPrefab.