I'm new to unity and I'm trying to follow this tutorial: https://www.youtube.com/watch?v=7iYWpzL9GkM&t=1600s
But when I do the code at 42:00 and compile my character wont move at all. I wont to believe I did everything exactly as the video explains but I cant figure out how to fix it.
Here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine;
//Take and handle input and movement from the character
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 1f;
public float collisionOffset = 0.05f;
public ContactFilter2D movementFilter;
Vector2 movementInput;
Rigidbody2D rb;
List<RaycastHit2D> castCollisions = new List<RaycastHit2D>();
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void FixedUpdate(){
//If movement input is not 0, try to move
if(movementInput != Vector2.zero){
bool success = TryMove(movementInput);
if(!success){
success = TryMove(new Vector2(movementInput.x, 0));
}
if(!success){
success = TryMove(new Vector2(0, movementInput.y));
}
}
}
private bool TryMove(Vector2 direccion){
//Check for Potencial Collisions
int count = rb.Cast(
direccion, // X and Y values between -1 and 1 that represent the direction from the body to look for collision
movementFilter, // The setting that determines where a collision can occur on such as layers to collide with
castCollisions, // Lists of collisions to store the found collisions into after the Cast is finished
moveSpeed = Time.fixedDeltaTime + collisionOffset); // The amount to cast equal to the movement plus an offset
if(count == 0){
rb.MovePosition(rb.position * direccion * moveSpeed * Time.fixedDeltaTime);
return true;
} else{
return false;
}
}
void OnMove(InputValue movementValue){
movementInput = movementValue.Get<Vector2>();
}
}
If anyone can help I really appreciate it.
Input System: version 1.3.0
Visual Studio Code Editor: version 1.2.5
Test Framework: version 1.1.33
Unity: version 2021.3.7f1
Your should change direccion to direction in TryMove.
You should make sure you have all your values in the inspector assigned to the according thing. eg. rb should be assigned to your character and your character should have the rigidBody attached to it.
Hope this helps, tell me if it still doesn't work.
Related
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyControler : MonoBehaviour
{
private Transform player;
// Start is called before the first frame update
void Start()
{
//Note in this case we're saving the transform in a variable to work with later.
//We could save the player's game object (and just remove .transform from the below) but this is cleaner
var player = GameObject.FindWithTag("Player").transform;
}
// Update is called once per frame
void Update()
{
//**** The code below you need to modify and move into your own method and call that method from here.
//**** Don't overthink it. Look at how Start() is defined. Your own Move method would look the exact same.
//**** Experiment making it private void instead of public void. It should work the same.
//How much will we move by after 1 second? .5 meter
var step = .5f * Time.deltaTime; // 5 m/s
var newPosition = Vector3.MoveTowards(transform.position, player, step);//This is one way to move a game object by updating the transform. Watch the videos in this module and it should become apparent what goes here.
}
}
The transform does not map to the tagged player. I was trying to get an enemy in unity to move towards a moving player for a class, but I'm completely lost.
You had three issues in your code. The first was that you were defining a new player variable in the Start method. This hid the player member field you defined earlier.
The second issue was that you were getting a value to move towards, but you weren't assigning that value to the current objects position.
The third issue was that you were feeding in a Transform into the MoveTowards method, when you should have been feeding in a Vector2.
The code below should rectify these issues.
public class EnemyControler : MonoBehaviour
{
private Transform _player;
void Start()
{
_player = GameObject.FindWithTag("Player").transform;
}
void Update()
{
var step = .5f * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, _player.position, step);
}
}
Try doing something like this ive used this in the past to do something similar once you understand the code change it to what you desire
public int minRange;
private Transform target = null;
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
target = other.transform;
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
target = null;
}
void update()
{
transform.LookAt(target);
float distance = Vector3.Distance(transform.position,
target.position);
bool tooClose = distance < minRange;
Vector3 direction = tooClose ? Vector3.back : Vector3.forward;
if (direction == Vector3.forward)
{
transform.Translate(direction * 6 * Time.deltaTime);
}
else
{
transform.Translate(direction * 3 * Time.deltaTime);
}
}
noob here.
I am currently using a tutorial to make my first little 2d platformer.
With the use of a script, my character can move left and right. The issue I am having is
getting the sprite to jump.
Below is my code:
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController2D Controller;
public float RunSpeed = 40f;
bool Jump = false;
float horizontalMove = 0f;
// Update is called once per frame
void Update()
{
horizontalMove = Input.GetAxisRaw("Horizontal") * RunSpeed;
if (Input.GetButtonDown("Jump"))
{
UnityEngine.Debug.Log("This works");
Jump = true;
}
}
private void FixedUpdate()
{
Controller.Move(horizontalMove * Time.fixedDeltaTime, false, Jump);
Jump = false;
}
}
The debug line does execute in the console my the Code registers my press of the space button, however, nothing happens to the little man on screen.
I hope someone can help.
Many Thanks,
Ellis
the value you use in Controller.Move() to specify the force of the jump seems to be 0.
If you change horizontalMove to a public float you can assign a value to it in the unity editor or you can assign a value in the script.
Good luck.
EDIT:
Sorry, Immortality is right. You already set horizontalMove.
Input.GetAxisRaw can be -1,0 or 1. So horizontalMove can become -40, 0 or 40. Because you multiply in your controller arguments with Time.deltaTime - and deltaTime often being around 0.005 - your argument becauses roughly (-)0.2. I don't know what your controller does with that value but I guess that's the reason why you don't see anything. The value is just to small
I am trying to set up control of Player game object by UI buttons.
2d top down view scene.
I want to transfer Player object smoothly on fixed distance (0.8 for Axix X for left-right direction and 2.4 for up-down)when I release left/right/up/down ui buttons.
Here i found code for smooth movement but there Player is moving all the time while ui button is pressed.
Can you help me to make it move on mouse up (pointer up) and to move for public x= 0.8f for left/right, and public y = 2.4f for up/down
And at the same time i want to use different speed (peblic) for moves on x and y Axis
Its ok if it should be totally other script using smth like transform.translate
Kindly guide to for any possible solution for this. Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class PlayerControl : MonoBehaviour
{
float movX;
float movY;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
movX = CrossPlatformInputManager.GetAxisRaw("Horizontal");
movY = CrossPlatformInputManager.GetAxisRaw("Vertical");
rb.velocity = new Vector2(movX * 1, movY * 1);
}
}
This script can be moved by the WASD keys.
This should move your gameObject by the requested amount over x amount of time(speed).
Currently it can be only moved when it'S reached its destionation but you can easily modify this :), by stopping the coroutine
using System.Collections;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// We gonna move by WASD keys
[Header("Speed & Movement settings")]
[SerializeField]
float Speed = 2.0f;
[SerializeField]
float movSpeedX = 0.8f;
[SerializeField]
float movSpeedY = 2.4f;
bool ReachedTarget = true;
void Update()
{
if (ReachedTarget)
{
Vector2 dest = Vector2.zero;
Vector2 currentPos = transform.position;
if (Input.GetKeyUp(KeyCode.W))
{
dest = currentPos + (Vector2.up * movSpeedY);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.S))
{
dest = currentPos + (Vector2.down * movSpeedY);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.D))
{
dest = currentPos + (Vector2.right * movSpeedX);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.A))
{
dest = currentPos + (Vector2.left * movSpeedX);
StartCoroutine(moveTo(dest, Speed));
}
}
}
// Time to take is in seconds
IEnumerator moveTo(Vector2 TargetPosition, float TimetoTake)
{
Vector2 originalPosition = transform.position;
float Time_taken = 0f;
ReachedTarget = false;
while (Time_taken < 1)
{
Time_taken += Time.deltaTime / TimetoTake;
// Interpolating between the original and target position this basically provides your "speed"
transform.position = Vector2.Lerp(originalPosition, TargetPosition, Time_taken);
yield return null;
}
Time_taken = 0;
transform.position = TargetPosition;
ReachedTarget = true;
}
}
I can't find any documentation of CrossPlatformInputManager, and I know nothing about it. But if you need to get the event of "release a key" instead of "press the key", try this: Input.GetKeyUp.
Description
Returns true during the frame the user releases the key identified by
name.
You need to call this function from the Update function, since the
state gets reset each frame. It will not return true until the user
has pressed the key and released it again.
For the list of key identifiers see Conventional Game Input. When
dealing with input it is recommended to use Input.GetAxis and
Input.GetButton instead since it allows end-users to configure the
keys.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void Update()
{
if (Input.GetKeyUp("space"))
{
print("Space key was released");
}
}
}
If you want to stop the rigid body, you need to reset its velocity to
zero. Or you can use
Rigidbody2D.MovePosition
to move it a certain distance.
Parameters
position The new position for the Rigidbody object.
Description
Moves the rigidbody to position.
Moves the rigidbody to the specified position by calculating the
appropriate linear velocity required to move the rigidbody to that
position during the next physics update. During the move, neither
gravity or linear drag will affect the body. This causes the object to
rapidly move from the existing position, through the world, to the
specified position.
Because this feature allows a rigidbody to be moved rapidly to the
specified position through the world, any colliders attached to the
rigidbody will react as expected i.e. they will produce collisions
and/or triggers. This also means that if the colliders produce a
collision then it will affect the rigidbody movement and potentially
stop it from reaching the specified position during the next physics
update. If the rigidbody is kinematic then any collisions won't affect
the rigidbody itself and will only affect any other dynamic colliders.
2D rigidbodies have a fixed limit on how fast they can move therefore
attempting to move large distances over short time-scales can result
in the rigidbody not reaching the specified position during the next
physics update. It is recommended that you use this for relatively
small distance movements only.
It is important to understand that the actual position change will
only occur during the next physics update therefore calling this
method repeatedly without waiting for the next physics update will
result in the last call being used. For this reason, it is recommended
that it is called during the FixedUpdate callback.
Note: MovePosition is intended for use with kinematic rigidbodies.
// Move sprite bottom left to upper right. It does not stop moving.
// The Rigidbody2D gives the position for the cube.
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour
{
public Texture2D tex;
private Vector2 velocity;
private Rigidbody2D rb2D;
private Sprite mySprite;
private SpriteRenderer sr;
void Awake()
{
sr = gameObject.AddComponent<SpriteRenderer>();
rb2D = gameObject.AddComponent<Rigidbody2D>();
}
void Start()
{
mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f);
velocity = new Vector2(1.75f, 1.1f);
sr.color = new Color(0.9f, 0.9f, 0.0f, 1.0f);
transform.position = new Vector3(-2.0f, -2.0f, 0.0f);
sr.sprite = mySprite;
}
void FixedUpdate()
{
rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
}
}
Both documents have an example.
Or you don't want to user keyboard but UI buttons, try this: IPointerDownHandler and IPointerUpHandler
Description
Interface to implement if you wish to receive OnPointerDown callbacks.
Detects ongoing mouse clicks until release of the mouse button. Use
IPointerUpHandler to handle the release of the mouse button.
//Attach this script to the GameObject you would like to have mouse clicks detected on
//This script outputs a message to the Console when a click is currently detected or when it is released on the GameObject with this script attached
using UnityEngine;
using UnityEngine.EventSystems;
public class Example : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
//Detect current clicks on the GameObject (the one with the script attached)
public void OnPointerDown(PointerEventData pointerEventData)
{
//Output the name of the GameObject that is being clicked
Debug.Log(name + "Game Object Click in Progress");
}
//Detect if clicks are no longer registering
public void OnPointerUp(PointerEventData pointerEventData)
{
Debug.Log(name + "No longer being clicked");
}
}
I am very new to Unity and I never coded in C# before neither have I used Unity in the past. All I know is Java and Python. I knew Java since senior year of high school now I am a sophomore in college. I made my project, which consists of my human character, which is supposed to shoot bullets at 12 jaguars. I already implemented all of this from the 2d UFO sample Unity gives us. I have a png picture for my bullet. I really do not know how to implement a bullet. I am required to have the bullet shoot out in two directions. I am starting off gradually by learning how to basic shoot (one direction). I referred to this link and added it to my program and it will not compile after I added the bullet code. I create a sphere into the Unity program as the website said to do and I set the image as the png bullet.
https://unity3d.com/learn/tutorials/temas/multiplayer-networking/shooting-single-player
Now here is my code. I downloaded the free latest version of Unity by the way. My game is 2D by the way. It is just cartoons.
using UnityEngine;
using System.Collections;
//Adding this allows us to access members of the UI namespace including Text.
using UnityEngine.UI;
public class CompletePlayerController : MonoBehaviour {
public float speed; //Floating point variable to store the player's movement speed.
public Text countText; //Store a reference to the UI Text component which will display the number of pickups collected.
public Text winText; //Store a reference to the UI Text component which will display the 'You win' message.
private Rigidbody2D rb2d; //Store a reference to the Rigidbody2D component required to use 2D Physics.
private int count; //Integer to store the number of pickups collected so far.
public GameObject bulletPrefab;
public Transform bulletSpawn;
// Use this for initialization
void Start()
{
//Get and store a reference to the Rigidbody2D component so that we can access it.
rb2d = GetComponent<Rigidbody2D> ();
//Initialize count to zero.
count = 0;
//Initialze winText to a blank string since we haven't won yet at beginning.
winText.text = "";
//Call our SetCountText function which will update the text with the current value for count.
SetCountText ();
}
//FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
void FixedUpdate()
{
//Store the current horizontal input in the float moveHorizontal.
float moveHorizontal = Input.GetAxis ("Horizontal");
//Store the current vertical input in the float moveVertical.
float moveVertical = Input.GetAxis ("Vertical");
//Use the two store floats to create a new Vector2 variable movement.
Vector2 movement = new Vector2 (moveHorizontal, moveVertical);
//Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
rb2d.AddForce (movement * speed);
if (!isLocalPlayer)
{
return;
}
var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate(0, x, 0);
transform.Translate(0, 0, z);
if (Input.GetKeyDown(KeyCode.Space))
{
Fire();
}
}
void Fire()
{
// Create the Bullet from the Bullet Prefab
var bullet = (GameObject)Instantiate (
bulletPrefab,
bulletSpawn.position,
bulletSpawn.rotation);
// Add velocity to the bullet
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6;
// Destroy the bullet after 2 seconds
Destroy(bullet, 2.0f);
}
public override void OnStartLocalPlayer ()
{
GetComponent<MeshRenderer>().material.color = Color.blue;
}
//OnTriggerEnter2D is called whenever this object overlaps with a trigger collider.
void OnTriggerEnter2D(Collider2D other)
{
//Check the provided Collider2D parameter other to see if it is tagged "PickUp", if it is...
if (other.gameObject.CompareTag ("PickUp"))
{
//... then set the other object we just collided with to inactive.
other.gameObject.SetActive(false);
transform.localScale += new Vector3(0.1f, 0.1f, 0);
//Add one to the current value of our count variable.
count = count + 1;
//Update the currently displayed count by calling the SetCountText function.
SetCountText ();
}
}
//This function updates the text displaying the number of objects we've collected and displays our victory message if we've collected all of them.
void SetCountText()
{
//Set the text property of our our countText object to "Count: " followed by the number stored in our count variable.
countText.text = "Count: " + count.ToString ();
//Check if we've collected all 12 pickups. If we have...
if (count >= 12)
//... then set the text property of our winText object to "You win!"
winText.text = "You win!";
}
}
Other class
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour {
public GameObject player; //Public variable to store a reference to the player game object
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.
transform.position = player.transform.position + offset;
}
}
You need to follow all the steps in the tutorial link you shared. Looks like you have copied pieces of code and used it in your controller class. OnStartLocalPlayer is marked as overridden, but it is not in Monobehaviour. It is defined in NetworkBehaviour. You have an error due to this. As mentioned in the other comments, the console error tells you where the problem is.
I currently have a little issue with a script I made. Basically, I want to create a script that makes its GameObject (let's name it A) and follows another GameObject's (named B) position. I know a simple way to do that would be to parent A to B, but I'm not doing it for two reasons :
1) I want to be able to apply a smoothing (whose value I can change) on A's movement;
2) I want to be able to make A follow B's position and/or rotation at will.
Here is the script I wrote :
using UnityEngine;
using System.Collections;
public class FollowGameObject : MonoBehaviour {
public GameObject m_GameObjectToFollow;
public bool m_FollowPosition;
public bool m_FollowRotation;
public float m_PositionSmoothing;
public float m_RotationSmoothing;
// Should not be changed once set
public bool m_UseOffsetPosition;
public bool m_UseOffsetRotation;
private Vector3 m_PositionOffset;
private Quaternion m_RotationOffset;
void Start () {
m_PositionSmoothing = Mathf.Clamp(m_PositionSmoothing, 0.0f, 1.0f);
m_RotationSmoothing = Mathf.Clamp(m_RotationSmoothing, 0.0f, 1.0f);
if (m_UseOffsetPosition)
{
m_PositionOffset = transform.position - m_GameObjectToFollow.transform.position;
} else {
m_PositionOffset = Vector3.zero;
}
if (m_UseOffsetRotation)
{
m_RotationOffset = transform.rotation * Quaternion.Inverse(m_GameObjectToFollow.transform.rotation);
} else {
m_RotationOffset = Quaternion.identity;
}
}
void FixedUpdate () {
if (m_FollowPosition) {
Vector3 goalPosition = m_GameObjectToFollow.transform.position + m_PositionOffset;
transform.position = Vector3.Lerp(transform.position, goalPosition, m_PositionSmoothing);
//transform.Translate(newPosition - transform.position, Space.World);
}
if (m_FollowRotation) {
Quaternion goalRotation = m_GameObjectToFollow.transform.rotation * m_RotationOffset;
transform.rotation = Quaternion.Lerp(transform.rotation, goalRotation, m_RotationSmoothing);
}
}
I hope the code is easily understandable, if not feel free to ask.
In any case, once I attach this script to A and assign its m_GameObjectToFollow attribute to B (B is parented to a character controller, and I parented a sphere renderer to A so I can see if it follows B correctly), I notice that A is indeed following B, but I see that its position (through the sphere renderer) is "fluctuating" between the "right" position (B's) and another one. Visually, the sphere is flickering.
I tried putting the smoothing values to 1 (i.e. A should always be at B's position/rotation). I still see a flickering.
Could someone explain to me what I did wrong?
EDIT : Seems like I'm using Lerp the wrong way with its last value. I modified the script to use speed values instead of smoothing values, but still the same problem when I try to create some smooth movements (with lower speed values).
I have troubles explaining the problem properly. The best way to see what the problem look like would be to experience it yourself :
1) Create a scene with a terrain and a character controller in it;
2) Parent the main camera to the controller (so that it always follows it);
3) Create a new GameObject with a renderer (for example, a sphere), not parented to any other GameObject, but attach the following script to it :
using UnityEngine;
using System.Collections;
public class FollowGameObject : MonoBehaviour {
public GameObject m_GameObjectToFollow;
public bool m_FollowPosition;
public bool m_FollowRotation;
// Betzeen 0 and 1. 1 means that a complete unsmoothed follow
public float m_PositionFollowSpeed;
public float m_RotationFollowSpeed;
// Should not be changed once set
public bool m_UseOffsetPosition;
public bool m_UseOffsetRotation;
private Vector3 m_PositionOffset;
private Quaternion m_RotationOffset;
void Start () {
if (m_UseOffsetPosition)
{
m_PositionOffset = transform.position - m_GameObjectToFollow.transform.position;
} else {
m_PositionOffset = Vector3.zero;
}
if (m_UseOffsetRotation)
{
m_RotationOffset = transform.rotation * Quaternion.Inverse(m_GameObjectToFollow.transform.rotation);
} else {
m_RotationOffset = Quaternion.identity;
}
}
void Update () {
if (m_FollowPosition) {
Vector3 goalPosition = m_GameObjectToFollow.transform.position + m_PositionOffset;
transform.position = Vector3.Slerp(transform.position, goalPosition, Time.deltaTime * m_PositionFollowSpeed);
}
if (m_FollowRotation) {
Quaternion goalRotation = m_GameObjectToFollow.transform.rotation * m_RotationOffset;
transform.rotation = Quaternion.Slerp(transform.rotation, goalRotation, Time.deltaTime * m_RotationFollowSpeed);
}
}
}
With :
m_GameObjectToFollow = the character controller GameObject;
m_FollowPosition = true;
m_PositionFollowSpeed = 10;
(The other parameters values don't matter for this test)
Now start the scene and move the character controller, I will see the sphere flickering during motion, but if you stop moving it will smoothly go to the controller.
You are using FixedUpdate. Is there any special reason to do so?
Anyway, try to use Update or LateUpdate instead of FixedUpdate or check Fixed Timestep in Project Settings => Time.
Also read the answer to this question for more information about difference between Update and FixedUpdate.