I was trying to make an endless game from youtube video https://www.youtube.com/watch?v=xTTBbXYH9BA&t=585s. In the video, the code is working properly. But in my Visual Studio, it saying "Vector3 does not contain a constructor that takes four arguments".
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
private bool ismovingright = false;
[SerializeField]
float speed = 4f;
void Start ()
{
rb = this.GetComponent<Rigidbody>();
}
private Rigidbody rb;
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
ChangeBoolean();
ChangeDirection();
}
}
private void ChangeBoolean()
{
ismovingright = !ismovingright;
}
private void ChangeDirection()
{
if (ismovingright)
{
rb.velocity = new Vector3(speed, 0f, 0f,);
}
else
{
rb.velocity = new Vector3(0f, 0f, speed);
}
}
}
You have a typo, there is an additional comma after 0f
if (ismovingright)
{
rb.velocity = new Vector3(speed, 0f, 0f,);
}else
Related
I was making a platform that bounces the player after a certain period of time when the player touches it. I attached this code component to the GameObject, which is a tilemap, and it doesn't work properly. What's wrong with my code? The code and scriptable object are as follows.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExplosionPlatform : PlatformBase
{
public float explosionPower = 20f;
public float waitTime = 1.5f;
public float colTime = 0f;
public bool isDamageOnce = false;
public Vector2 area = new Vector2(2, 2);
public Vector2 positionModify = new Vector2(1, 0);
private void OnCollisionEnter2D(Collision2D collision)
{
StartCoroutine(Explosion());
}
private IEnumerator Explosion()
{
Debug.Log("ASDF");
yield return new WaitForSeconds(waitTime);
Collider2D[] player = Physics2D.OverlapBoxAll(transform.position + (Vector3)positionModify, area, 0);
foreach (Collider2D col in player)
{
if (col.CompareTag("Player"))
{
col.gameObject.GetComponent<Rigidbody2D>().AddForce(Vector2.up * explosionPower, ForceMode2D.Impulse);
Damage();
isDamageOnce = true;
yield return new WaitForSeconds(3f);
isDamageOnce = false;
}
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireCube(transform.position + (Vector3)positionModify, area);
}
}
I have confirmed that the code below works properly on GameObject, which is Unity 2d Sprite. Is there any way to use that code while using the tile map?
i started my first game project and i'm stuck with my dash
my dash randomly starts working when i press dash button (R) but it's not always working. i'm new to the gamedev and tried looking for solutions - like FixedUpdate or AddForce or transform.position - but nothing helps. if you have any ideas could you help me?
my code is below
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
private BoxCollider2D coll;
private int jumpCount = 1;
private bool canDash = true;
private bool isDashing;
[SerializeField] private LayerMask jumpableGround;
// Start is called before the first frame update
private void Start()
{
rb = GetComponent<Rigidbody2D>();
coll = GetComponent<BoxCollider2D>();
}
// Update is called once per frame
private void Update()
{
float dirX = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(dirX * 7f, rb.velocity.y);
if (Input.GetButtonDown("Jump") && jumpCount != 0)
{
rb.velocity = new Vector2(rb.velocity.x, 12f);
jumpCount--;
}
if (IsGrounded())
{
jumpCount = 1;
}
if(Input.GetKeyDown(KeyCode.R) && canDash)
{
_ = StartCoroutine(Dash());
}
}
private bool IsGrounded()
{
return Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, .1f, jumpableGround);
}
private IEnumerator Dash()
{
canDash = false;
float originalGravity = rb.gravityScale;
rb.gravityScale = 0f;
rb.velocity = new Vector2(rb.velocity.x, 0f);
rb.AddForce(new Vector2(rb.velocity.x * 24f, 0f), ForceMode2D.Impulse);
Debug.Log("something");
rb.gravityScale = originalGravity;
yield return new WaitForSeconds(0.1f);
canDash = true;
}
}
It looks like you are overriding the velocity on each call to Update():
rb.velocity = new Vector2(dirX * 7f, rb.velocity.y);
You can probably add a field for "_isDashing", and if the user is dashing don't override the velocity.
If you're not fully using the built in physics engine, you may need to also track the dash direction. For example some logic like "If not dashing, update velocity as normal. If dashing, update velocity and dash direction to appropriate settings".
I am trying to create a multiplayer TPS where I instantiate a bullet locally (in my editor) and apply force to it. Once it hits other player I would want to call that players TakeDamage RPC.
Sadly I am encountering this weird error message that I can't fix (already taking me days).
my projectile script:
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Arrow : MonoBehaviour
{
[SerializeField] float timeToDestroy;
[SerializeField] ParticleSystem hitEffect;
[SerializeField] TrailRenderer trailRenderer;
float timer;
private Rigidbody rb;
private Collider col;
private void Awake()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
}
private void Update()
{
timer += Time.deltaTime;
if (timer > timeToDestroy) Destroy(gameObject);
}
private void OnCollisionEnter(Collision collision)
{
rb.isKinematic = true;
rb.velocity = Vector3.zero;
trailRenderer.enabled = false;
ShowHitEffect(collision.GetContact(0));
col.enabled = false;
if (collision.gameObject.CompareTag("Player"))
{
rb.isKinematic = true;
rb.velocity = Vector3.zero;
trailRenderer.enabled = false;
PhotonView pv = collision.gameObject.GetPhotonView();
Debug.Log("hit " + pv.Controller.NickName);
pv.RPC("DealDamage", RpcTarget.All, PhotonNetwork.LocalPlayer.NickName, .5f, PhotonNetwork.LocalPlayer.ActorNumber);
}
Destroy(gameObject, 2f);
}
private void ShowHitEffect(ContactPoint cp)
{
hitEffect.transform.position = cp.point;
hitEffect.transform.forward = cp.normal;
hitEffect.Emit(1);
}
}
weapon controller script
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponController : MonoBehaviourPunCallbacks
{
[Header("Fire Rate")]
[SerializeField] float fireRate;
float fireRateTimer;
[SerializeField] bool semiAuto;
[Header("Bullet Property")]
[SerializeField] GameObject bullet;
[SerializeField] Transform barrelPos;
[SerializeField] float bulletVelocity;
[SerializeField] byte bulletPerShot;
public AimController aim;
[SerializeField] AudioClip gunshot;
public AudioSource audioSource;
public WeaponAmmo ammo;
public ParticleSystem muzzleFlash;
public ParticleSystem hitEffect;
// Start is called before the first frame update
void Start()
{
fireRateTimer = fireRate;
}
private void Update()
{
if (!photonView.IsMine) return;
if (ShouldFire()) Fire();
}
bool ShouldFire()
{
fireRateTimer += Time.deltaTime;
if (fireRateTimer < fireRate) return false;
if (ammo.currentAmmo == 0) return false;
if (semiAuto && Input.GetKeyDown(KeyCode.Mouse0)) return true;
if (!semiAuto && Input.GetKey(KeyCode.Mouse0)) return true;
return false;
}
[PunRPC]
private void EmitMuzzleFlash()
{
muzzleFlash.Emit(1);
}
void Fire()
{
fireRateTimer = 0;
barrelPos.LookAt(aim.actualAimPos);
audioSource.PlayOneShot(gunshot);
EmitMuzzleFlash();
//photonView.RPC("EmitMuzzleFlash", RpcTarget.All);
ammo.currentAmmo--;
for (int i = 0; i < bulletPerShot; i++)
{
GameObject currentBullet = Instantiate(bullet, barrelPos.position, barrelPos.rotation);
Rigidbody rigidbody = currentBullet.GetComponent<Rigidbody>();
rigidbody.AddForce(barrelPos.forward * bulletVelocity, ForceMode.Impulse);
// Projectile Instantiate
/*{
GameObject currentProjectile = (GameObject)PhotonNetwork.Instantiate(bullet.name, barrelPos.position, barrelPos.rotation);
Rigidbody rb = currentProjectile.GetComponent<Rigidbody>();
rb.AddForce(barrelPos.forward * bulletVelocity, ForceMode.Impulse);
}*/
}
}
}
player controller script (where rpc is located)
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviourPunCallbacks
{
private PlayerStats stats = new PlayerStats();
void Start()
{
if (photonView.IsMine)
{
UIController.instance.healthSlider.maxValue = stats.maxHealth;
UIController.instance.healthSlider.value = stats.GetCurrentHealth();
}
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
FocusWindows();
}
void FocusWindows()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Cursor.lockState = CursorLockMode.None;
}
else if (Cursor.lockState == CursorLockMode.None)
{
if (Input.GetMouseButton(0))
{
Cursor.lockState = CursorLockMode.Locked;
}
}
}
#region
[PunRPC]
public void DealDamage(string damager, float damageAmount, int actor)
{
Debug.Log("called rpc deal damage");
Debug.Log("damager " + damager + " damageAmount " + damageAmount + " actor " + actor);
TakeDamage(damager, damageAmount, actor);
}
public void TakeDamage(string damager, float damageAmount, int actor)
{
if (photonView.IsMine)
{
stats.ReduceHealth(damageAmount);
if (stats.GetCurrentHealth() == 0)
{
PlayerSpawner.Instance.Die(damager);
MatchManager.instance.UpdateStatSend(actor, 0, 1);
}
UIController.instance.healthSlider.value = stats.GetCurrentHealth();
}
}
#endregion
}
Projectile Prefab(resource)
enter image description here
Player prefab
enter image description here
Weird thing is if I go with "Instantiate Arrow in the network" the rpc is getting called. But this is not ideal since it will because it will send the transform of the projectile every time it is flying. So I just want to check in the local (arrow with no photonView) if it hits an enemy then call the rpc of that enemy to make him take damage and possibly display a fake project coming from the damager. If my approach is naive / wrong please tell me a better approach please.
I transfered the rpc call on the same script where the photonView is located as mentioned by #derHugo. I think the main problem was my understanding of RPC. I thought rpc is like a public method where you can call it outside. I think I need to reread the documentations about rpc and raise events.
I am currently building my first multiplayer game in unity and having a little bit of an issue changing/transmitting the players direction over the network.
My current player controls class is this:
using UnityEngine;
using System.Collections;
public class playerControls : MonoBehaviour {
#region
//Vars
//Movements Vars
public float runSpeed;
Rigidbody mybody;
Animator myAnimator;
bool playerDirectionE;
#endregion
// Use this for initialization
void Start () {
mybody = GetComponent<Rigidbody>();
myAnimator = GetComponent<Animator>();
playerDirectionE = true;
mybody.transform.eulerAngles = new Vector3(0, 90, 0);
}
// Update is called once per frame
void Update () {
}
void FixedUpdate()
{
float move = Input.GetAxis("Horizontal");
myAnimator.SetFloat("speed", Mathf.Abs(move)); //To intiate the charecter transition(move)
mybody.velocity = new Vector3(move * runSpeed, mybody.velocity.y, 0); //move charecter along the x axis, and keep y on gravity, not touching the z axis
if(move>0 && !playerDirectionE)
{
Flip();
}
else if(move<0 && playerDirectionE)
{
Flip();
}
}
void Flip()
{
playerDirectionE = !playerDirectionE;
Vector3 theScale = transform.localScale;
theScale.z *= -1;
transform.localScale = theScale;
}
}
I am using the following client information to send commands over the network:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;
public class PlayerSyncRotation : NetworkBehaviour {
[SyncVar(hook ="OnPlayerRotSynced")]
private float syncPlayerRotation;
[SerializeField]
private Transform playerTransform;
private float lerpRate = 15;
private float lastPlayerRot;
private float threshold = 1;
private List<float> syncPlayerRotList = new List<float>();
private float closeEneough = 0.3f;
[SerializeField]
private bool userHistoricalInterpolation;
[Client]
void OnPlayerRotSynced(float latestPlayerRotation)
{
syncPlayerRotation = latestPlayerRotation;
syncPlayerRotList.Add(syncPlayerRotation);
}
[Command]
void CmdProvideRotationsToServer(float playerRot)
{
syncPlayerRotation = playerRot;
}
[Client]
void transmitRotations()
{
if (isLocalPlayer)
{
if(CheckIfBeyondThreshold(playerTransform.localScale.z, lastPlayerRot)){
lastPlayerRot = playerTransform.localScale.z;
CmdProvideRotationsToServer(lastPlayerRot);
}
}
}
bool CheckIfBeyondThreshold(float rot1, float rot2)
{
if (Mathf.Abs(rot1 - rot2) > threshold)
{
return true;
}
else
{
return false;
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
lerpRotation();
}
void FixedUpdate()
{
transmitRotations();
}
void lerpRotation()
{
if (!isLocalPlayer)
{
HistoricalInterpolation();
}
}
void HistoricalInterpolation(){
if (syncPlayerRotList.Count > 0)
{
LerpPlayerRotation(syncPlayerRotList[0]);
if(Mathf.Abs(playerTransform.localEulerAngles.z - syncPlayerRotList[0]) < closeEneough)
{
syncPlayerRotList.RemoveAt(0);
}
Debug.Log(syncPlayerRotList.Count.ToString() + "syncPlayerRotList Count");
}
}
void LerpPlayerRotation(float rotAngle)
{
Vector3 playerNewRot = new Vector3(0, 0, rotAngle);
playerTransform.rotation = Quaternion.Lerp(playerTransform.rotation, Quaternion.Euler(playerNewRot),lerpRate*Time.deltaTime);
}
}
My rotation looks fine on the client, but over the network on the second client, the rotation is broken and looks very wrong.
I have attached a link to a Webm where you can see the short video snippet of my problem HERE.
Would anyone here have any input as to what I could be doing wrong or how I could fix this issue? any suggestions would be appreciated.
Instead Using your custom code, i will like to say you that use Unet NetworkTransform. It is Unet high level API with different option of customization.
A component to synchronize the position and rotation of networked
objects(more).
Unet HLAPI are open source so you can also get the coding of the networkTransform at bitbucket.
The issue is I can only move upwards if the user holds the E key. Is there a way to have the user press the E key then just have the lift start?
Here's my code:
using UnityEngine;
using System.Collections;
public class liftScript : MonoBehaviour {
public int speed = 1;
private int i = 10;
void OnTriggerStay()
{
startLift ();
}
void startLift()
{
if(Input.GetKey(KeyCode.E)) {
transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x, 10, transform.position.z), Time.deltaTime * speed);
}
}
}
i think you can modify your code
public class liftScript : MonoBehaviour {
public int speed = 1;
private int i = 10;
bool keyPressed = false;
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.E)) {
keyPressed = true;
}
if (keyPressed == true)
{
startLift();
}
}
void startLift()
{
transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x, 10, transform.position.z), Time.deltaTime * speed);
}
void stopLift()
{
keyPressed = false;
}
}
Hope it can help you