I am making a 2D game where you control a shield and you have to block falling obstacles from reaching base. I know that to move something you use rb.addforce. However, when I do the same for 2D it doesn't work. I imagine that instead of using a Vector3 you use a Vector2, but it gives me these 2 errors: Assets\Movement.cs(16,25): error CS1503: Argument 1: cannot convert from 'float' to 'UnityEngine.Vector2' and this one: Assets\Movement.cs(16,25): error CS1503: Argument 1: cannot convert from 'float' to 'UnityEngine.Vector2' for each time I write the line. Here is my full code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public Rigidbody2D rb;
public Collider2D collider;
public float moveSpeed = 0.1f;
private void Update()
{
if (Input.GetKey("w"))
{
rb.AddForce(0f, moveSpeed);
Debug.Log("w");
}
if (Input.GetKey("s"))
{
rb.AddForce(0f, moveSpeed);
Debug.Log("s");
}
}
}
You can add a new Vector2 in rb.AddForce (new Vector2(0,moveSpeed));
Here is the updated code:
public class Movement : MonoBehaviour
{
public Rigidbody2D rb;
public Collider2D collider;
public float moveSpeed = 0.1f;
private void Update()
{
if (Input.GetKey("w"))
{
rb.AddForce(new Vector2(0f, moveSpeed));
Debug.Log("w");
}
if (Input.GetKey("s"))
{
rb.AddForce(new Vector2 (0f, moveSpeed));
Debug.Log("s");
}
}
}
Rigidbody2D.AddForce doesn't take two float parameters but rather as usual a Vector2 and a ForceMode2D where the latter has a default value of ForceMode2D.Force if you don't pass it in.
So your code should rather be
// = new Vector2 (0,1) * moveSpeed
// = new Vector2 (0, moveSpeed)
rb.AddForce(Vector2.up * moveSpeed);
...
// I assume in the second case you rather want to go down so
// = new Vector2 (0, -1) * moveSpeed
// = new Vector2 (0, -moveSpeed)
rb.AddForce(Vector2.down * moveSpeed);
Btw I would rather not Debug.Log every frame in Update it's pretty expensive.
Related
FIRST : SORRY FOR MY ENGLISH !!!
Hello everyone, i'm very new into Unity (5 days).
Today i've make a script for the basics movements with a rigid-bodie, BUT the diagonal movements are faster than the normal movements.. I search on Internet but I don't find a post that i can understand.
So here my script.
Also if you know how to not move when we jump, or when we jump into a direction, it follow this direction, tell me. (I know my english is terrible.) Also, i'm new into this website.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovements : MonoBehaviour
{
[SerializeField] private float walkingSpeed;
[SerializeField] private float runningSpeed;
[SerializeField] private float jumpForce;
[SerializeField] private float jumpRaycastDistance;
private Rigidbody rb;
float speed;
Vector3 movement;
/////////////////////////////////////////////////////
void Start()
{
rb = GetComponent<Rigidbody>();
}
/////////////////////////////////////////////////////
void Update()
{
Jumping();
}
/////////////////////////////////////////////////////
private void FixedUpdate()
{
Movements();
}
/////////////////////////////////////////////////////
private void Movements()
{
float hAxis = Input.GetAxisRaw("Horizontal");
float vAxis = Input.GetAxisRaw("Vertical");
if(Input.GetButton("Run"))
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * runningSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
else
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * walkingSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
}
/////////////////////////////////////////////////////
private void Jumping()
{
if(Input.GetButtonDown("Jump"))
{
if (isGrounded())
{
rb.AddForce(0, jumpForce, 0, ForceMode.Impulse);
}
}
}
/////////////////////////////////////////////////////
private bool isGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, jumpRaycastDistance);
}
}
You need to clamp your velocity in order to keep it same. Look into Vector3.ClampMagnitude()
velocity = Vector3.ClampMagnitude(velocity, _movementSpeed);
velocity.y = playerVelocity.Y; // keeping your Y velocity same since you have jumping.
playerVelocity = velocity;
EDIT: in your case it should be something like this.
_maxSpeed is the speed limit.
private void FixedUpdate()
{
Movements();
var clampedVelocity = Vector3.ClampMagnitude(rb.velocity, _maxSpeed);
clampedVelocity.y = rb.velocity.y;
rb.velocity = clampedVelocity;
}
Try normalizing the vector. (more info is on unity docs, but normalize() will make sure that the sum of all the vector's values isnt above 1.
I am making the enemy character to follow the player character.
In the FixedUpdate method the enemy character move toward the player character,
then in the Update method character rotates to the player character.
However, with this script, somehow enemy character is just nudging and gets stuck.
Where is the mistake, what's wrong???
public class enemy : MonoBehaviour
{
GameObject tObj;
private Vector3 latestPos;
public string targetObjectName;
public float speed = (float)1.0;
void Start()
{
tObj = GameObject.Find("player");
latestPos = transform.position;
}
void Update()
{
Vector3 diff = transform.position - latestPos;
latestPos = transform.position;
if (diff.magnitude > 0.01f)
{
transform.rotation = Quaternion.LookRotation(diff);
}
}
void FixedUpdate(){
Vector3 dir = (tObj.transform.position - this.transform.position).normalized;
float vx = dir.x * speed;
float vz = dir.z * speed;
this.transform.Translate((float)(vx / 50.0),0,(float)(vz / 50.0));
}
}
Use Package Manager "Standard Assets", Inside Unity put two FPSController one should be Player and the second can be Enemy.
I know this does not answers your question but its a faster way to ad Enemy.
AI Settings
Just remove the camera, Audio Source and First Person Controller Script as in image.
The Code for AI:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowAI : MonoBehaviour
{
public CharacterController _controller;
public Transform target;
public GameObject Player;
[SerializeField]
float _moveSpeed = 2.0f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update() {
Vector3 direction = target.position - transform.position;
direction = direction.normalized;
Vector3 velocity = direction * _moveSpeed;
_controller.Move(velocity * Time.deltaTime);
Vector3 lookVector = Player.transform.position - transform.position;
lookVector.y = transform.position.y;
Quaternion rot = Quaternion.LookRotation(lookVector);
transform.rotation = Quaternion.Slerp(transform.rotation, rot, 1);
}
}
I dont understand how I can make this shotgun jumps in my version of Unity: https://www.youtube.com/watch?v=FUkdz8jYt3w
How does this work?
Im using "First Person Controller" that looks like capsule
There are images: https://imgur.com/a/uvfAePX
This is for old version of Unity 4.5.5. I've tried RigidBody, but nothing happened. I've tried Transform, but again, no result.
First Person Controller:
using UnityEngine;
using System.Collections;
public class run : MonoBehaviour
{
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
public Transform character;
public int CharacterForce = 5000;
public int time = 1;
void Update()
{
CharacterController controller =
GetComponent<CharacterController>();
if (controller.isGrounded)
{
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis ("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move (moveDirection * Time.deltaTime);
if (Input.GetMouseButtonDown(0))
{
Transform BulletInstance = (Transform)Instantiate(character, GameObject.Find("CameraRSP").transform.position, Quaternion.identity);
BulletInstance.GetComponent<Rigidbody>().AddForce(transform.forward * CharacterForce);
}
}
}
"Grenade" code:
using UnityEngine;
using System.Collections;
public class grenade : MonoBehaviour
{
public Transform GrenadeF;
public int force = 500;
public float radius;
void Start()
{
Collider[] col = Physics.OverlapSphere(transform.position, radius);
foreach (Collider c in col)
{
c.GetComponent<Rigidbody>().AddExplosionForce(force, transform.position, radius);
}
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, radius);
}
}
When I used Transform I expected that this would work in ANY direction, but it worked in only one.
When I used RigidBody I expected that this would WORK, but my capsule didnt even moved.
Checkout the optional upwardsModifier parameter of
AddExplosionForce(float explosionForce, Vector3 explosionPosition, float explosionRadius, float upwardsModifier = 0.0f, ForceMode mode = ForceMode.Force));
(The API for Unity 4 is no longer available but I guess it should have been the same there)
Adjustment to the apparent position of the explosion to make it seem to lift objects.
and
Using this parameter, you can make the explosion appear to throw objects up into the air, which can give a more dramatic effect rather than a simple outward force. Force can be applied only to an active rigidbody.
By default it is 0 so if you don't pass it there won't be any upwards force.
As you can see in the example from the API
Vector3 explosionPos = transform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
foreach (Collider hit in colliders)
{
Rigidbody rb = hit.GetComponent<Rigidbody>();
// |
// v
if (rb) rb.AddExplosionForce(power, explosionPos, radius, 3.0f);
}
they passed e.g. 3.0f as upwardsModifier. This makes the explosion
appear to be centred 3.0 units below its actual position for purposes of calculating the force direction (ie, the centre and the radius of effect are not modified).
Note: Typed on smartphone so no warrenty but I hope the idea gets clear
I am trying to complete roll a ball tutorial (https://unity3d.com/learn/tutorials/projects/roll-ball-tutorial) in a different way by adding two balls.
So two players can play the game.
But the problem i am facing is that i want to configure the preferred keys for the second player like the firsl player uses the traditional arrow keys and the second player use w,a,s,d to move up left down right... my c-sharp code for the first player is this...
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public float speed;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody> ();
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); //Values for movement vector 3 takes three arguments like x y z for positions.
rb.AddForce (movement * speed);
}
}
Let me know if anyone have solution
Answered Similar question here.
The easiest solution that will require you not modify your key controls is to not use Input.GetAxis at-all. Detect each key press with Input.GetKey() and their keycodes enum. Problem solved! Now assign the two balls from the Editor. You can easily modify it to work with one ball if that's what you want.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float speed = 80.0f; // Code for how fast the ball can move. Also it will be public so we can change it inside of Unity itself.
public Rigidbody player1RB; //Player 1 Rigidbody
public Rigidbody player2RB; //Player 2 Rigidbody
//Player 1 Code with aswd keys
void Player1Movement()
{
if (Input.GetKey(KeyCode.A))
{
player1RB.AddForce(Vector3.left * speed);
}
if (Input.GetKey(KeyCode.D))
{
player1RB.AddForce(Vector3.right * speed);
}
if (Input.GetKey(KeyCode.W))
{
player1RB.AddForce(Vector3.forward * speed);
}
if (Input.GetKey(KeyCode.S))
{
player1RB.AddForce(Vector3.back * speed);
}
}
//Player 2 Code with arrow keys
void Player2Movement()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
player2RB.AddForce(Vector3.left * speed);
}
if (Input.GetKey(KeyCode.RightArrow))
{
player2RB.AddForce(Vector3.right * speed);
}
if (Input.GetKey(KeyCode.UpArrow))
{
player2RB.AddForce(Vector3.forward * speed);
}
if (Input.GetKey(KeyCode.DownArrow))
{
player2RB.AddForce(Vector3.back * speed);
}
}
// Update is called once per frame
void FixedUpdate()
{
Player1Movement();
Player2Movement();
}
}
You can define more inputs in edit -> project settings -> Input. To add more inputs just increase the size value and config the new values in. At least input name and keys to the new inputs. Lastly, in your code call the new inputs for player 2 with the names you specified in the project settings.
void FixedUpdate()
{
//float moveHorizontal = Input.GetAxis("Horizontal");
//float moveVertical = Input.GetAxis("Vertical");
// example for player 2
float moveHorizontalPlayer2 = Input.GetAxis("HorizontalPlayer2");
float moveVerticalPlayer2 = Input.GetAxis("VerticalPlayer2");
Vector3 movement = new Vector3 (moveHorizontalPlayer2 , 0.0f, moveVerticalPlayer2 );
rb.AddForce (movement * speed);
}
Good day everyone!
I'm starting up in Unity 5 AND C# and I'm following a tutorial, thing is... the tutorial was made for Unity 4, therefore some of the code in the tutorial is not usable in U5. This time my problem is with scripting audio to an action, here follows the code:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
public float xMin, xMax, zMin, zMax;
}
public class PlayerController : MonoBehaviour
{
public float speed;
public float tilt;
public Boundary boundary;
public GameObject shot;
public float fireRate;
public Transform shotSpawn;
private float nextFire;
void Update()
{
if (Input.GetButton ("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
Audio.Play(); <---
}
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
Rigidbody rb = GetComponent<Rigidbody> ();
rb.velocity = movement * speed;
rb.position = new Vector3
(
Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax)
);
rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt);
}
}
So there you go, the line "audio.Play();" is not compiled as there's nothing in U5 even close to that syntax. Can anyone give me a hint here?
Thanks in advance!
Instead of using Audio.play() use GetComponent<AudioSource>().Play(); and make sure you have an Audiosource attached to the gameobject.
Add a variable 'AudioClip' and assign the clip to an audiosource.. Then use getComponent.Play();
Java:
var myClip : AudioClip;
function Start () {
AudioSource.PlayClipAtPoint(myClip, transform.position);
}
c#:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SoundController : MonoBehaviour {
public AudioClip clip;
void Start () {
AudioSource.PlayClipAtPoint(clip, Vector3.zero, 1.0f);
}
}
If you want play audio in instantiate you can use this:
#pragma strict
var prefabBullet : Transform;
var forwardForce = 1000;
var myClip : AudioClip;
function Update()
{
if (Input.GetButtonDown("Fire2"))
{
var instanceBullet = Instantiate (prefabBullet, transform.position,
Quaternion.identity);
instanceBullet.GetComponent.<Rigidbody>().AddForce(transform.forward *
forwardForce);
AudioSource.PlayClipAtPoint(myClip, transform.position);
}
}