In Unity, I am programming a top-down game where if the player does damage to an enemy, the enemy would be knocked back opposite of the direction of the attack. The code I currently have moves the enemy downwards, regardless of the position of the player's attack. This game was created in Unity3D. The enemy has a CharacterController component attached to it.
public void OnTriggerEnter(Collider col)
{
//...
Vector3 knockBack = col.transform.position - transform.position; //Used to calculate the direction of the knockback.
GetComponent<CharacterController>().Move (knockBack);
//...
}
I am sure I am missing something, but what? I have tried using the rotation of the objects, and the -transform.forward of the player, but it does not seem to have an effect on the direction of the movement. Thank you for your time.
Related
I have been making a first person game called "shoot the ball into the bin". The camera is in a cylinder as a player also the cylinder has collision.
I have been struggling with the main driver of the game. Like in most first person shooter games, you shoot out from the center point of the camera or the cursor.
I have trouble replicating that. The code I have so far for the shooting is:
Instantiate(prefab, new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, Camera.main.transform.position.z), Camera.main.transform.rotation);
(Credits to #derHugo for helping me instantiate a prefab)
But that just spawns it on top of the player, not in front of it. How do I make it shoot away from the player, but also in front of the player, not on top.
In order to spawn in front of that position simply use
// Already reference this via the Inspector if possible
[SerializeField] private Camera _camera;
// Adjust how far in front of the camera the object should spawn
[SerializeField] private float distance;
private void Awake ()
{
// otherwise get it ONCE
if(!_camera) _camera = Camera.main;
}
And then simply add an offset in the direction of Transform.forward of the camera like
Instantiate(prefab, _camera.transform.position + _camera.transform.forward * distance, _camera.transform.rotation);
so it seems when you instantiate the bullets, you are spawning them directly on the position of the camera. You should adjust those values so that it spawns in the center of the screen. To do so, you should divide the y position by 2 or 1.5 depending on how high up the gun is from the ground. Then change the z so that the bullets pushed further in front of the player.
Instantiate(prefab, new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y / 2, Camera.main.transform.position.z + somearbitraryvalue), Camera.main.transform.rotation);
Next, to get give the bullets a velocity, you should create a separate script for the bullet prefab that is in charge of moving the bullets.
public Rigidbody2D bullet;
bullet = GetComponent<Rigidbody2D>()
void Update(){
bullet.velocity = new Vector 3(0,0,1)
}
Hope this answer helps!
I am making a game in Unity 2D and i wanted the bullet the player shoots from his gun to bounce after it hits a wall. The script i made for the bullet is this:
public float speed = 40f;
public Rigidbody2D rb;
private Vector2 direction;
public void Start()
{
rb.velocity = transform.right * speed;
}
private void OnCollisionEnter2D(Collision2D collision)
{
Vector2 inNormal = collision.contacts[0].normal;
direction = Vector2.Reflect(rb.velocity, inNormal);
rb.velocity = direction * speed;
}
I put a 2D physics material on the colliders which has 1.15 friction and 0.1 bounciness to make the ball bounce (as it wouldn't bounce before without the material) but now the ball bounces off the wall with a different speed every time I shoot it. Sometimes the speed of the bullet is so high it passes through the wall and that is not intended at all. Instead I wanted the ball to bounce with the same speed from wall to wall, but I don't know how to fix this problem. Can someone help me?
You don't need this onCollision part of code to have it bounce, thats a point of having rigidbody, collider and material. unity does calculations for you.
Make bullet dynamic body, if it moves too fast to detect colision change Collision detection" in Rigidbody(on wall but perhapsalso on bullet) from discrete to continous.
And it should bounce.
If angle and speed is always the same result will also always be the same.
I suspect you have wieird results becouse you are ovverriding actual colision.
I'm making a game which involves rotating around a point shooting enemies before they reach said point, in 2D. However, as the enemies are going to be spawned in random places around the game, I need to make them rotate towards the centre to start moving in that direction. Here is the code that doesn't function properly:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public Rigidbody2D rb;
//this is the enemy, by the way
public Transform follow;
public void Start()
{
transform.LookAt(Vector2.zero);
rb.velocity = follow.up; //'up' worked in my bullet script for heading in the direction the player was facing
}
}
Instead of the knob rotating and slowly moving towards the point, the knob weirdly elongates and then begins to move towards the top of the screen, but at a slight angle. It's probably a stupid mistake, as I've only been writing in C# and using Unity for about a week.
However, any help would be greatly appreciated!
Edit: After clarification, this is my answer:
You should use Vector3.MoveTowards.
void Update ()
{
enemy.transform.position = Vector3.MoveTowards(enemy.transform.position, point.transform.position, speed * Time.deltaTime);
}
I would recommend attaching this to your enemy game object and replacing enemy.transform.position; with gameObject.transform.position;. This way you can make an enemy prefab later on and easily spawn as many as you need.
https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html
Sorry if I don't understand fully, but you want the enemys to rotate and move towards the center of the screen?
If so, you can use transform.Rotate(rotation * Time.deltaTime); to rotate the enemys and transform.Translate(vector * Time.deltaTime);to move them towards a point.
Add the game object you want to move to the method. Eg, if this were going to be attached to your enemies script you would write gameObject.transform.Rotate(rotation * Time.deltaTime);.
If you wanted the enemys to circle around something you could create a 'point' game object then attach the rotate script to it. Then make the enemies children of that object so they rotate with it. Then, put the translate script on the enemys so they move towards the point.
Hope this helps!
https://docs.unity3d.com/ScriptReference/Transform-rotation.html
https://docs.unity3d.com/ScriptReference/Transform.Translate.html
Try this. Transform.LookAt might not be working for 2d. See this for similar example.
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public Rigidbody2D rb;
public float speed = 1f;
public Transform follow; //this is the enemy, by the way
public void Start()
{
//depending how your enemy points (is its forward direction x axis or y axis) you should either use transform.right or transform.up
transform.right = follow.position - transform.position;
// or use transform.up = follow.position - transform.position;
rb.velocity = transform.right * speed; // change transform.right to transform.up if you use transform.up above.
}
}
void OnCollisionEnter(Collision col){
if (col.gameObject.name == "Enemy1") {
enemyDamage++;
GameObject clone = (GameObject) Instantiate (tempBloodSplat,enemyObj.position,enemyObj.rotation);
Destroy (clone , 0.5f);
if (enemyDamage > 3) {
anim.SetFloat ("Die", 0.5f);
Destroy (enemyObj.gameObject , 5.0f);
}
Debug.Log ("Bullet is hitting Enemy");
}
}
This is my code, i used on BulletObject
My Bullet Object has Collider
My Enemy has a Collider
My Enemy has a Rigidbody
Bullet is not having Rigidbody
I have problem that when i shoot, the bullet is hitting the Enemy in his range, like the circle under the body of the Enemy,Image
Sometimes the bullet hits correctly (means enemy is damaged), but sometimes the bullet moves out without making any damage to the enemy,I don't know why its happening.Does the velocity of the bullet has any effect on it..
Please help or guide me to solve this problem, Thanks
If you are not using a rigidbody on the bullet, then you are probably updating the bullets position vector directly, and what could be happening is the following:
. Since the bullet is not a rigidbody, Unity does not 'assume' it should behave like one and thus does not do an actual physics simulation of the bullet movement (which would probably include a raycast from start position to end position and colision checking in between). If you have a problem with adding a rigidbody to the bullet, then do the raycast yourself. You will even learn a bit of how the physics simulation behind unity actually might work!
Good Luck!
I am new to programming and I am making a 2D side-scrolling beat em' up for my project. I got an AI working for my enemies but my enemy objects are modelled to be flat so only one side is meant to be shown. When I start my game, the enemies immediately rotates to face the player when i wanted it to stay as it is but still move towards the player.
http://i.imgur.com/TJYtfro.png This is what I want the enemies to stay as, just having this face shown as it slides towards the player without rotating or tilting.
http://i.imgur.com/n0gI2Rf.png This is what happens when I start the game which is why I do not want the objects to rotate or tilt. If you want additional informations of what I have done or if I am unclear, just let me know. It is my first time asking online.
This is the code I got for the enemyAI. I know the code is all wrong when it comes to what I wanna achieve but I have very limited coding knowledge and still learning.
//------------Variables----------------//
public Transform target;
public int moveSpeed;
public int rotationSpeed;
public int maxdistance;
private Transform myTransform;
//------------------------------------//
void Awake()
{
myTransform = transform;
}
void Start ()
{
maxdistance = 2;
}
void Update ()
{
if(Vector3.Distance(target.position, myTransform.position) > maxdistance)
{
//Move towards target
transform.LookAt (target.position);
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
}
}
Your problem is that you have some confusion over what "forward" means. You need to decide which direction forward is. Currently, "forward " is "out of the screen", because you're doing a 2D side scroller and you have all of your enemies facing out of the screen.
However, you're trying to use LookAt() to make the characters look at the player. But then of course they'll turn, because "forward" for each enemy mesh/model is currently the direction facing out from their face.
You have two options. One is to rotate all of your models 90 degrees so that forward is coming out their side. In this case, you could still use LookAt() and then tell the enemies to move forward, but visually they'd still be looking out of the screen. However, the enemies would turn around backwards if you got onto their other side. So probably not a good option.
The other option is that you shouldn't be setting the enemy transform/position using the "forward" vector. Just set the enemy position based on a vector that's the difference between the enemy position and the player position. Subtract the enemy position vector from the player position vector and you'll have a vector pointing in the direction of the player. Normalize it to get a unit direction vector. Then multiply that by the move speed and delta time as you have above. Use that instead of "forward" and your enemies will toward the player. In this case, you don't call the LookAt() at all, because you always want the enemies facing out of the screen.
EDIT: I don't have a copy of Unity, but it should be something like this:
if (Vector3.Distance(target.position, myTransform.position) > maxdistance)
{
// Get a direction vector from us to the target
Vector3 dir = target.position - myTransform.position;
// Normalize it so that it's a unit direction vector
dir.Normalize();
// Move ourselves in that direction
myTransform.position += dir * moveSpeed * Time.deltaTime;
}