I was trying to create a car in unity using a C# Script, everything seems to be fine, the car rotates left and right, except 1 problem. when I press the forward or backwards keys, the car moves left and right instead of forward and backwards, I can't see anything wrong with my code, here's my code:
using UnityEngine;
using System.Collections;
public class Car : MonoBehaviour {
private Rigidbody carRigid;
public int speed;
public int rotateSpeed;
// Use this for initialization
void Start () {
carRigid = GetComponent<Rigidbody> ();
}
// Update is called once per frame
void Update () {
}
void FixedUpdate(){
if (Input.GetButton("Forward")){
carRigid.AddForce (transform.forward * speed * Time.deltaTime);
}
if (Input.GetButton("Reverse")){
carRigid.AddForce (transform.forward * -speed * Time.deltaTime);
}
if (Input.GetButton("Left")){
transform.Rotate (0, rotateSpeed, 0);
}
if (Input.GetButton("Right")){
transform.Rotate (0, rotateSpeed, 0);
}
}
}
Your car is moving on another axis which is different than the axis you want. try transform.right / transform.left or transform.up / transform.down .
I've just tested your code in a blank Unity scene, and I think you AddForce() is the culprit!
I used
if (Input.GetKey(KeyCode.W))
{
transform.position += transform.forward * speed * Time.deltaTime;
}
and this seems to be working great!
Maybe it's because you have imported a 3D model which it's local forward is not correct.
You have some choices:
1) Fix it in the 3d modeling program an export it again.
2) Create an empty GameObject and make this the parent of your car. Assign the rigid body and relevant codes to this GameObject and Rotate the car model in it's local space until it's fixed ( 90 degrees I guess).
3) use transform.right or transform.left depending on the rotation of your model.
I personally prefer first choice.
Related
First of all: Sorry for my bad English, I'm Dutch.
I'm trying to create a player object that can walk forward and backwards (with the up and down keys), and rotate the player with the right and left keys. But when I press the left or right key, the position of the player changes, it looks like it rotates around a certain point. But it should rotate and stay on the same place, like I do when I turn around.
I have some other small programs, with the same 'move script' and the same inputmanager settings. There it works fine, so I have no idea why it doesn't work this time.
This is my move script, but this script works fine with other programs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour
{
public float speed = 3f;
public float rotate = 50f;
private Rigidbody rb;
// Update is called once per frame
private void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetButton("Up"))
transform.Translate(Vector3.forward * speed * Time.deltaTime);
if (Input.GetButton("Down"))
transform.Translate(-Vector3.forward * speed * Time.deltaTime);
if (Input.GetButton("Right"))
transform.Rotate(Vector3.up, rotate * Time.deltaTime);
if (Input.GetButton("Left"))
transform.Rotate(-Vector3.up, rotate * Time.deltaTime);
if (gameObject.GetComponent<Rigidbody>().velocity.y < 0.01)
{
if (Input.GetButtonDown("Jump"))
rb.AddForce(0, 225, 0);
}
}
}
The InputManager settings (also the same as other programs where it works fine):
If someone wants a screenshot of something else of my program, you can always ask it of course. I have no idea what the problem could be, if it isn't in the script or the inputmanager.
Following the comments in the OP, the solution should be to use:
if (Input.GetButton("Right"))
transform.localEulerAngles = transform.localEulerAngles + new Vector3(xRotation, 0, 0) * Time.deltaTime;
if (Input.GetButton("Left"))
transform.localEulerAngles = transform.localEulerAngles - new Vector3(xRotation, 0, 0) * Time.deltaTime;
Where xRotation is a float with the amount you want to rotate per second when and while one of the rotation keys is down.
(PS: Don't have unity open right now, so + and - might be inverted, but should be something like that.)
I am using the Third Person Controller asset by Opsive. It is a fairly complex third person controller that controls animations, damage, movement, inputs, etc etc.
http://opsive.com/assets/ThirdPersonController/documentation.php
I would like to update the ControllerHandler.cs script to make the character move in the direction that the character is facing, regardless of camera orientation. (In the style of old Resident Evil games)
In the original script, the character would move forward in relation to which direction the camera was facing.
I received some advice to change a line in this script, but with the changes, the character moves forward in one fixed direction. (E.G.: When I turn to the right with the D key, and then press W to move forward, the character turns back in the direction he was originally facing and moves in that direction.)
Here is the original part of the script:
#if ENABLE_MULTIPLAYER
if ( isLocalPlayer) {
#endif
if (m_Controller.Movement == RigidbodyCharacterController.MovementType.Combat || m_Controller.Movement == RigidbodyCharacterController.MovementType.Adventure) {
m_LookRotation = m_CameraTransform.rotation;
Here is what someone told me to change it to:
#if ENABLE_MULTIPLAYER
if ( isLocalPlayer) {
#endif
if (m_Controller.Movement == RigidbodyCharacterController.MovementType.Combat || m_Controller.Movement == RigidbodyCharacterController.MovementType.Adventure) {
m_LookRotation = Quaternion.Euler(PlayerInput.GetAxisRaw(Constants.YawInputName), 0, 0);
Unfortunately, this does not have the result that I intended.
Any assistance would be greatly appreciated. Thanks!
Here is a link to the controller script:
https://docs.google.com/document/d/1B4sstqtCqRMCLuHuxEuA9I7tO_3W4aHqEZwr73uFDjY/edit?usp=sharing
I think you want
transform.position += transform.rotation * Vector3.forward;
A complete block of code would look like this...
void Update() {
if (Input.GetKey(KeyCode.W)) {
transform.position += transform.rotation * Vector3.forward * MOVESPEED;
}
}
I have got it working. Take a look at the picture first it will help you set up the player correctly. My player is just two cubes. I added the second cube to give a face to where the player is pointing. I have added those 2 cube to a parent object and I move the parent object with my PlayerMovement.cs.
public float rotSpeed;
public float playerSpeed;
void Update()
{
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate( Vector3.up, Time.deltaTime * rotSpeed);
} else if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(-Vector3.up, Time.deltaTime * rotSpeed);
}
if (Input.GetKey(KeyCode.UpArrow))
{
transform.Translate(Vector3.forward * Time.deltaTime * playerSpeed);
} else if (Input.GetKey(KeyCode.DownArrow))
{
transform.Translate(-Vector3.forward * Time.deltaTime * playerSpeed);
}
}
I've been programming like an hour or so, then i realice that in unity 5 the charactercontroller.isGrounded doesn't work. Could anyone give me a answer?
This is the code i had
public float playerSpeed = 3f;
public float realSpeed = 3f;
public float jumpSpeed= 7f;
public float sprintSpeed= 5f;
public float gravity = 20f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
CharacterController CC = GetComponent<CharacterController>();
if(Input.GetKey(KeyCode.W)){
transform.Translate(Vector3.forward * playerSpeed* Time.deltaTime);
}
if(Input.GetKey(KeyCode.S)){
transform.Translate(Vector3.back * playerSpeed* Time.deltaTime);
}
if(Input.GetKey(KeyCode.D)){
transform.Translate(Vector3.right * playerSpeed* Time.deltaTime);
}
if(Input.GetKey(KeyCode.A)){
transform.Translate(Vector3.left * playerSpeed* Time.deltaTime);
}
if(Input.GetKey(KeyCode.Space) && CC.isGrounded){
transform.Translate(Vector3.up * jumpSpeed* Time.deltaTime);
}
if (Input.GetKey(KeyCode.LeftShift)) {
playerSpeed = sprintSpeed;
} else {
playerSpeed = realSpeed;
}
}
}`
So you're trying to make your character jump but only when it's on the ground?
I had this problem before a well. My solution was to make an empty gameobject and place it as a child of your character and a little bit and then put a collider as a trigger on your empty object.
Then you can have collision detection on your empty object to detect whether it is ontriggerstay on just the bottom side. It also compensates for little bumps and stuff.
According to your code you are not using any character controller. You are just changing the position of Object by using translate which will never collide with your ground. Where as to use character controller you have to provide a move direction with gravity to character controller so that its will use character controller to move your player. Gravity vector will pull your character downward and collide with ground then isGrounded will be true. Check Character Controller implementation in this unity script reference for detail.
When reading this, keep in mind I'm new to both programming and Unity, so I might be missing some terms or tools Unity offer. Please elaborate your answers in an ELI5 manner. Thanks in advance!
I am currently working on some game-physics for a small personal project. Currently I've created a platform, a character and what should be, a following companion.
However, since I'm still not on a level, where I can create perfect code on own hand, I found an "enemy" script and tried to modify it a bit.
It Works to an extend, but it needs some tweaks which I hope I can help aquire with you guys.
This is how it looks now (the orange square is the companion)
It follows the player, and I can tweak the speed to fit as a companion, and not a player. However, as the Picture presents, the companion runs for the center of the player. What I want to create is a companion which follows the player, but still keeps a small gap from the player.
My first thoughts was to create some kind of permanent offset, but I fail to figure out how to do this without messing up the follow function.
I hope you can help me, it will be much appreciated!
Here's the code for reference.
Code attached to Player:
using UnityEngine;
using System.Collections;
public class PlayerCompanion : MonoBehaviour
{
//In the editor, add your wayPoint gameobject to the script.
public GameObject wayPoint;
//This is how often your waypoint's position will update to the player's position
private float timer = 0.5f;
void Update ()
{
if (timer > 0) {
timer -= Time.deltaTime;
}
if (timer <= 0) {
//The position of the waypoint will update to the player's position
UpdatePosition ();
timer = 0.5f;
}
}
void UpdatePosition ()
{
//The wayPoint's position will now be the player's current position.
wayPoint.transform.position = transform.position;
}
}
Code attached to companion:
using UnityEngine;
using System.Collections;
public class FollowerOffset : MonoBehaviour {
//You may consider adding a rigid body to the zombie for accurate physics simulation
private GameObject wayPoint;
private Vector3 wayPointPos;
//This will be the zombie's speed. Adjust as necessary.
private float speed = 10.0f;
void Start ()
{
//At the start of the game, the zombies will find the gameobject called wayPoint.
wayPoint = GameObject.Find("wayPoint");
}
void Update ()
{
wayPointPos = new Vector3(wayPoint.transform.position.x, transform.position.y, wayPoint.transform.position.z);
//Here, the zombie's will follow the waypoint.
transform.position = Vector3.MoveTowards(transform.position, wayPointPos, speed * Time.deltaTime);
}
}
bump, I guess ? :)
You can use smooth follow script. I have created a sample class for you. This class has features to follow any given gameobject with some delay and offset. You will have to tweak some values according to your need.
using UnityEngine;
using System.Collections;
public class PlayerCompanion : MonoBehaviour
{
[SerializeField]
private GameObject wayPoint;
[SerializeField]
public Vector3 offset;
public Vector3 targetPos;//Edit: I forgot to declare this on firt time
public float interpVelocity;
public float cameraLerpTime = .1f;
public float followStrength = 15f;
// Use this for initialization
void Start ()
{
//At the start of the game, the zombies will find the gameobject called wayPoint.
wayPoint = GameObject.Find("wayPoint");
offset = new Vector3 (5,0,0);//input amount of offset you need
}
void FixedUpdate () {
if (wayPoint) {
Vector3 posNoZ = transform.position;
Vector3 targetDirection = (wayPoint.transform.position - posNoZ);
interpVelocity = targetDirection.magnitude * followStrength;
targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime);
transform.position = Vector3.Lerp (transform.position, targetPos + offset, cameraLerpTime);
}
}
}
Attach this class to your player companion, play with different values.
To preserve object orientation your companion schould not be anyways child of your main character.
Your wayPoint doesn't needs to be a GameObject but a Transform instead and your code will looks like better.
If your game is a 2D platform your and your companion needs to be backwards your player it probabli applys to just one axis (X?) so you can decrement your waiPoint in a more directly way by calculating it on your UpdatePosition function like this:
wayPoint.position = transform.position * (Vector3.left * distance);
where your "distance" could be a public float to easily setup.
so on your companion script Update just do:
transform.position = Vector3.MoveTowards(transform.position, wayPoint.position, speed * Time.deltaTime);
I can't test it right now so you could have problems with Vector3 multiply operations, just comment and I'll try to fix as possible ;)
Does anyone have a good jumping script for 2d games in unity? The code I have works but still is far from jumping, it looks like it is flying.
using UnityEngine;
using System.Collections;
public class movingplayer : MonoBehaviour {
public Vector2 speed = new Vector2(10,10);
private Vector2 movement = new Vector2(1,1);
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float inputX = Input.GetAxis ("Horizontal");
float inputY = Input.GetAxis ("Vertical");
movement = new Vector2(
speed.x * inputX,
speed.y * inputY);
if (Input.GetKeyDown ("space")){
transform.Translate(Vector3.up * 260 * Time.deltaTime, Space.World);
}
}
void FixedUpdate()
{
// 5 - Move the game object
rigidbody2D.velocity = movement;
//rigidbody2D.AddForce(movement);
}
}
Usually for jumping people use Rigidbody2D.AddForce with Forcemode.Impulse. It may seem like your object is pushed once in Y axis and it will fall down automatically due to gravity.
Example:
rigidbody2D.AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
The answer above is now obsolete with Unity 5 or newer. Use this instead!
GetComponent<Rigidbody2D>().AddForce(new Vector2(0,10), ForceMode2D.Impulse);
I also want to add that this leaves the jump height super private and only editable in the script, so this is what I did...
public float playerSpeed; //allows us to be able to change speed in Unity
public Vector2 jumpHeight;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
transform.Translate(playerSpeed * Time.deltaTime, 0f, 0f); //makes player run
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space)) //makes player jump
{
GetComponent<Rigidbody2D>().AddForce(jumpHeight, ForceMode2D.Impulse);
This makes it to where you can edit the jump height in Unity itself without having to go back to the script.
Side note - I wanted to comment on the answer above, but I can't because I'm new here. :)
Use Addforce() method of a rigidbody compenent, make sure rigidbody is attached to the object and gravity is enabled,
something like this
gameObj.rigidbody2D.AddForce(Vector3.up * 10 * Time.deltaTime); or
gameObj.rigidbody2D.AddForce(Vector3.up * 1000);
See which combination and what values matches your requirement and use accordingly.
Hope it helps