I recently started working in Unity. I'm pretty new and have only been working with the software for a day, so I was creating a very basic movement script when an error popped up prompting me to close a curly bracket. I did so, but the error persisted. I think my code is fine, what's going on? I'm sure I'm probably just being an idiot.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Movement : MonoBehaviour {
[SerializeField] private int speed = 10;
[SerializeField] private int jump_height = 200;
[SerializeField] private float m_smoothing = 0.14;
private Vector3 m_Velocity = Vector3.zero;
Rigidbody2D m_Rigidbody;
public void Start()
{
m_Rigidbody = GetComponent<Rigidbody2D>();
}
public void Update()
{
[SerializeField] private float playerInputh = Input.GetAxisRaw("Horizontal");
Vector3 targetVelocity = new Vector2(playerInputh * speed, m_Rigidbody.velocity.y);
m_Rigidbody.velocity = Vector3.SmoothDamp(m_Rigidbody.velocity, targetVelocity, ref m_Velocity, m_smoothing);
if (Input.GetKeyDown("space"))
{
m_Rigidbody.AddForce(new Vector2(0f, jump_height));
}
}
}
The variable "m smoothing" is of type float, and numbers of type float must be accompanied with an f after the end.
For example 5 is of type int or float, 5.0 is of type float and should be written 5.0f, and 0.14 is of type float and should be written 0.14f.
The other problem is that you have entered [SerializeField] private in a method. To declare a local variable, that is, it can be called up only in that method, just write the type and name, and if you want, then assign it a value.
Learn more, because I have simplified some things, but I hope I have been clear.
Here is your error-free code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Movement : MonoBehaviour
{
[SerializeField] private int speed = 10;
[SerializeField] private int jump_height = 200;
[SerializeField] private float m_smoothing = 0.14f;
private Vector3 m_Velocity = Vector3.zero;
Rigidbody2D m_Rigidbody;
public void Start()
{
m_Rigidbody = GetComponent<Rigidbody2D>();
}
public void Update()
{
float playerInputh = Input.GetAxisRaw("Horizontal");
Vector3 targetVelocity = new Vector2(playerInputh * speed, m_Rigidbody.velocity.y);
m_Rigidbody.velocity = Vector3.SmoothDamp(m_Rigidbody.velocity, targetVelocity, ref m_Velocity, m_smoothing);
if (Input.GetKeyDown("space"))
{
m_Rigidbody.AddForce(new Vector2(0f, jump_height));
}
}
}
if you think my answer helped you, you can mark it as accepted. I would very much appreciate it :)
Related
not for player movement but I need to network the AI's movement
well I haven't really tried anything because idk how to network movement
Basically you can use one of three approaches.
Easy mode
Add PhotonView and SimpleMode2D to your player
public SimpleMode2D : Monobehaviour {
[SerializeField] private PhotonView view;
[SerializeField] private float speed;
private void Update() {
if(!view.IsMine) return;
float h = Input.GetAxisRaw(“Horizontal”);
float v = Input.GetAxisRaw(“Vertical”);
gameObject.transform.position = new Vector2 (transform.position.x + (h * speed), transform.position.y + (v * speed));
}
RPCMode
You will still need to add PhotonView and RPCPlayer and to your player, but this time your movement control will be separately
public class RPCPlayer : Monobehaviour {
[PunRPC]
private void RPCMove(Vector2 newPosition){
transform.position = newPosition;
}
}
public RPCMode2D : Monobehaviour {
[SerializeField] private PhotonView player;
[SerializeField] private float speed;
private void Update() {
if(!player.IsMine) return;
float h = Input.GetAxisRaw(“Horizontal”);
float v = Input.GetAxisRaw(“Vertical”);
var position = player.transform.position;
player.RPC("RPCMove", new Vector2 (position.x + (h * speed), position.y + (v * speed)));
}
RaiseEvent Mode
Here you will need to create player instantiation/deletion and manipulation. I'm using this method because it more flexible but more complex. You can refer to documentation. Sorry here without code for now, I'll update this comment if you get interested in RaiseEvent usage.
So i am new to Mirror and i made this to learn a bit,it changes name of the host normally but when i try it on a client he just disconnects,and without any errors.I have setup many debug.log statements to see where is the problem and it seems that is not even executing as a client,it just stops before it was called.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using TMPro;
using System;`
public class PlayerMovement : NetworkBehaviour
{
public float speed;
float x, y;
Rigidbody2D rb;
Animator animator;
public TMP_InputField tmpf;
public TMP_Text nameText;
[SyncVar(hook = nameof(DisplayName))]
public string _name = "00";
void DisplayName(string oldName, string newName)
{
nameText.text = newName;
}
void Start()
{
if (!isLocalPlayer) return;
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
tmpf = GameObject.Find("NameIF").GetComponent<TMP_InputField>();
//tmpf.onValueChanged.AddListener(delegate { CmdChangeName(); });
}
void Update()
{
if (!isLocalPlayer) return;
x = Input.GetAxis("Horizontal");
y = Input.GetAxis("Vertical");
rb.velocity = new Vector2(x * speed, y * speed);
animator.SetFloat("horizontal", x);
animator.SetFloat("vertical", y);
if (Input.GetKeyDown(KeyCode.KeypadEnter))
{
CmdChangeName();
}
}
[Command]
public void CmdChangeName()
{
_name = tmpf.text;
}
How to fix this,i have client authority checked and i need to use commands if i want hooks and syncVar to work.
I've been working on endless platform spawner but I don't know how to use decimal number in code. I've been trying to use private double or private decimal but I didn't figure it out. Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlatformManager : MonoBehaviour
{
[SerializeField]
private GameObject[] _platformPrefabs;
[SerializeField]
private int _zedOffset;
private int _yOffset;
// Start is called before the first frame update
void Start()
{
for (int i = 0; 1 < _platformPrefabs.Length; i++)
{
global::System.Object value = Instantiate(_platformPrefabs[i], new Vector3(0, i * -24.8, i * -30), Quaternion.Euler(0, 90, 0));
_zedOffset += -30;
_yOffset += -24.8;
}
}
public void RecyclePlatform(GameObject platform)
{
platform.transform.position = new Vector3(0, _yOffset, _zedOffset);
_zedOffset += -30;
_yOffset += -24.8;
}
}
You need to use floats
private float _myFloat;
_myFloat = 1.23f;
I am tring to follow this tutorial https://www.youtube.com/watch?v=gmaAK_BXC4c to make a vr gun but I am getting an the following error:
'XRBaseInteractable' does not contain a definition for 'onSelectEntering' and no accessible extension method 'onSelectEntering' accepting a first argument of type 'XRBaseInteractable' could be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]csharp(CS1061)
for the following lines :
socketInteractor.onSelectEntering.AddListener(AddMagazine);
socketInteractor.onSelectExiting.AddListener(RemoveMagazine);
Here is my code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
[AddComponentMenu("Nokobot/Modern Guns/Simple Shoot")]
public class SimpleShoot : MonoBehaviour
{
[Header("Prefab Refrences")]
public GameObject bulletPrefab;
public GameObject casingPrefab;
public GameObject muzzleFlashPrefab;
[Header("Location Refrences")]
[SerializeField] private Animator gunAnimator;
[SerializeField] private Transform barrelLocation;
[SerializeField] private Transform casingExitLocation;
[Header("Settings")]
[Tooltip("Specify time to destory the casing object")] [SerializeField] private float destroyTimer = 2f;
[Tooltip("Bullet Speed")] [SerializeField] private float shotPower = 500f;
[Tooltip("Casing Ejection Speed")] [SerializeField] private float ejectPower = 150f;
public AudioSource source;
public AudioClip fireSound;
public AudioClip reload;
public Magazine magazine;
public AudioClip noAmmo;
public XRBaseInteractable socketInteractor;
public void AddMagazine(XRBaseInteractable interactable)
{
magazine = interactable.GetComponent<Magazine>();
source.PlayOneShot(reload);
}
public void RemoveMagazine(XRBaseInteractable interactable)
{
magazine = null;
}
public void Slide()
{
}
void Start()
{
if (barrelLocation == null)
barrelLocation = transform;
if (gunAnimator == null)
gunAnimator = GetComponentInChildren<Animator>();
socketInteractor.onSelectEntering.AddListener(AddMagazine);
socketInteractor.onSelectExiting.AddListener(RemoveMagazine);
}
public void PullTheTrigger()
{
if(magazine && magazine.numberOfBullet > 0)
{
gunAnimator.SetTrigger("Fire");
}
else
{
source.PlayOneShot(noAmmo);
}
}
//This function creates the bullet behavior
void Shoot()
{
magazine.numberOfBullet--;
source.PlayOneShot(fireSound);
if (muzzleFlashPrefab)
{
//Create the muzzle flash
GameObject tempFlash;
tempFlash = Instantiate(muzzleFlashPrefab, barrelLocation.position, barrelLocation.rotation);
//Destroy the muzzle flash effect
Destroy(tempFlash, destroyTimer);
}
//cancels if there's no bullet prefeb
if (!bulletPrefab)
{ return; }
// Create a bullet and add force on it in direction of the barrel
Instantiate(bulletPrefab, barrelLocation.position, barrelLocation.rotation).GetComponent<Rigidbody>().AddForce(barrelLocation.forward * shotPower);
}
//This function creates a casing at the ejection slot
void CasingRelease()
{
//Cancels function if ejection slot hasn't been set or there's no casing
if (!casingExitLocation || !casingPrefab)
{ return; }
//Create the casing
GameObject tempCasing;
tempCasing = Instantiate(casingPrefab, casingExitLocation.position, casingExitLocation.rotation) as GameObject;
//Add force on casing to push it out
tempCasing.GetComponent<Rigidbody>().AddExplosionForce(Random.Range(ejectPower * 0.7f, ejectPower), (casingExitLocation.position - casingExitLocation.right * 0.3f - casingExitLocation.up * 0.6f), 1f);
//Add torque to make casing spin in random direction
tempCasing.GetComponent<Rigidbody>().AddTorque(new Vector3(0, Random.Range(100f, 500f), Random.Range(100f, 1000f)), ForceMode.Impulse);
//Destroy casing after X seconds
Destroy(tempCasing, destroyTimer);
}
}
So I'm currently trying to add my player object with it's script into my camera script that is written for camera object.
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
private Vector3 offset;
private float damping = 0.2f;
public bool canMove = true;
public PlayerMovement player;
private void Start()
{
player = gameObject.GetComponent<PlayerMovement>();
}
void FixedUpdate()
{
if (player.faceRight)
{
offset = new Vector3(1f, 0.5f, -10f);
transform.position = Vector3.Lerp(transform.position, target.position, damping) + offset;
}
else if (!player.faceRight)
{
offset = new Vector3(-1f, 0.5f, -10f);
transform.position = Vector3.Lerp(transform.position, target.position, damping) + offset;
}
}
}
My problem is that I can't write player = gameObject.Find("Player"); because unity is saying something like "those are different types of elements" but I can drag my player object if I write public PlayerMovement player; and it works. The thing is I want to learn how to use that without dragging my object.
First of all you can expose and assign private (and protected) fields via the Inspector by using the attribute [SerializeField] without being forced to make them public like e.g.
[SerializeField] private PlayerMovement player;
private void Awake()
{
// if it's not referenced via the Inspector
// get it from this object on runtime as fallback
if(!player) player = GetComponent<PlayerMovement>();
}
And then, well, your field player is of type PlayerMovement while Find returns a GameObject → Not the same type.
Now if you want to get that component from the same object this script is attached to .. then why should you use the expensive Find at all?! You already know the object! Use only GetComponent to get the component attached tot he same object as this script (just like in the code above).
If you really want to use Find then you want to use GetComponent on the result, not on gameObject which is the reference to that scripts own GameObject. You would rather do
[SerializeField] private PlayerMovement player;
private void Awake()
{
if(!player) player = GameObject.Find("player").GetComponent<PlayerMovement>();
}
or if there is anyway only one instance of that type in your scene you can also simply use FindObjectOfType
[SerializeField] private PlayerMovement player;
private void Awake()
{
if(!player) player = FindObjectOfType<PlayerMovement>();
}
In general: If you can reference something via the Inspector it is always better doing so. It is way more efficient because the reference will be serialized into your scene or prefab asset so when it is loaded you already "know" the target reference. Using Find is very expensive and even though it was optimized a lot in later versions also GetComponent is work you could be avoiding ;)
I added my both GameObject and PlayerMovement attributes. Wrote gameObject first, which is called as "Player". Then by using my GameObject, I interacted with my script which is called PlayerMovement.
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
private Vector3 offset;
private float damping = 0.2f;
public bool canMove = true;
private GameObject playerObject;
private PlayerMovement playerMovementScript;
private void Start()
{
player = GameObject.Find("Player");
player = gameObject.GetComponent<PlayerMovement>();
}
void FixedUpdate()
{
if (player.faceRight)
{
offset = new Vector3(1f, 0.5f, -10f);
transform.position = Vector3.Lerp(transform.position, target.position, damping) + offset;
}
else if (!player.faceRight)
{
offset = new Vector3(-1f, 0.5f, -10f);
transform.position = Vector3.Lerp(transform.position, target.position, damping) + offset;
}
}
}
I fixed that problem when I was writing that issue here. So I'm kinda proud of myself but also I want to share my solution so if anyone encounter a problem like this, they can fix their problems. If anyone has better solution please share.