I have a problem with the camera rotation during the player vs AI game, when the white pawn moves, it rotates, but when the black AI pawn moves, it does not rotate to the side of the white pawns and, in addition, when it comes to positions, it does not set the camera correctly this problem does not occur during AI vs AI how to fix it
private void RotateCamera()
{
Vector3 cameraRotation = Camera.main.transform.rotation.eulerAngles;
if (IsWhiteTeam) //white=true !IsWhiteTeam = false black team
{
cameraRotation.y += 180f;
Camera.main.transform.position = new Vector3(0, 4, -5);
}
else
{
cameraRotation.y -= 180f;
Camera.main.transform.position = new Vector3(0, 4, 5);
}
Camera.main.transform.rotation = Quaternion.Euler(cameraRotation);
AI_System.chessBoard = this;
}
tried to change the positioning of the camera during the player vs AI game but it didn't help, please help me where am I making a mistake thanks in advance
Related
(I'm relatively new to Unity) I'm making a scene where I want the camera to move in the opposite direction of the mouse movement when I hold down the right mouse button.
The scene is isotropic, which is why the camera is orthographic.
[SerializeField] private Camera cam;
private Vector3 dragOrigin = Vector3.zero;
public float speed = 10;
void Update(){
if(Input.GetMouseButtonDown(1)){
dragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
}
if(Input.GetMouseButton(1)){
Vector3 difference = cam.ScreenToWorldPoint(Input.mousePosition) - cam.transform.position;
Vector3 targetPosition = dragOrigin - difference;
//targetPosition.y = cam.transform.position.y;
cam.transform.position = Vector3.Lerp(cam.transform.position, targetPosition, speed * Time.deltaTime);
}
}
This works, but there is the problem that the y-value of the camera changes as well. It should always stay at the same height.
If I use
targetPosition.y = cam.transform.position.y;
the camera stays on the same y-position, but it moves slower when I move it up and down.
How can I rewrite the code so that only the x and z values change and that the camera moves with the same speed in all directions?
Thanks in advance.
I've made a code for the enemy where it will go left and right and stop at the ledge, but for some reason the enemy will just disappear into thin air, but the enemy can still hit you, when I am going near where the enemy is located.
Here is the code I've made for the Enemy AI:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PatrollingEnemy : MonoBehaviour
{
public float speed;
private bool movingRight = true;
public Transform groundDetection; //detects the ground if it is there...
// Update is called once per frame
void Update()
{
transform.Translate(Vector2.right * speed * Time.deltaTime);
RaycastHit2D groundInfo = Physics2D.Raycast(groundDetection.position, Vector2.down, 2f);
if (groundInfo.collider == false)
{
if(movingRight == true)
{
transform.eulerAngles = new Vector2(0, -200);
movingRight = false;
}
else
{
transform.eulerAngles = new Vector2(0, 0);
movingRight = true;
}
}
}
}
Here is the link if you want to see how it works with this code: Link for Bug
It occurs because the z-axis value of the enemy transform decreases by time until it's less than the CAMERA z-axis value and moves outside the camera view.
The main problem is that you set transform.eulerAngles = new Vector2(0, -200); when the enemy moves to the left direction and when you combine this code with the transform.Translate(Vector2.right * speed * Time.deltaTime);, the enemy moves in its right vector with -200 angle and so after some times, it goes outside the camera view (Because the camera z-index is probably set to -10 by default).
You need to set the local angle of the y axis value to 180:
...
if (groundInfo.collider == false)
{
if(movingRight == true)
{
transform.eulerAngles = new Vector2(0, 180); // Change -200 to 180
movingRight = false;
}
...
}
...
ANOTHER WAY: if you want to change the enemy face direction to the left side, you can set localScale.x to -1 instead of using rotation.
Here is a simple example:
// Change face direction to the right when Moving RIGHT
transform.localScale= new Vector3(transform.localScale.x, transform.localScale.y, transform.localScale.z);
// Change face direction to the left when Moving LEFT
transform.localScale= new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
So, I'm trying to make something similar to Super Mario Galaxy's planet traversal where the player has to jump from planet to planet but the difference here is that the player is orbiting around the player instead of walking on it. I've managed to do the jumping from planet to planet but I have a small problem on where the players up direction is facing.
While landing somewhere in the middle of the planet the player changes his up direction in the opposite way he was facing when he first made the jump, if he lands somewhere close to the edge my logic fails.
As you can see in the photo bellow the Y axis is facing the wrong direction and it should face in the direction where the X axis is facing right now.
What would be the right logic to follow for the player Y axis to face the correct way?
// Jump from a planet
void Update()
{
if (TouchListener.Instance.Tap)
{
isOrbiting = false;
_rb.AddForce(transform.up * jumpForce, ForceMode2D.Impulse);
}
}
// Rotating around the planet
private void FixedUpdate()
{
if (planet != null && isOrbiting)
transform.RotateAround(planet.transform.localPosition, transform.forward * -1, orbitSpeed * Time.deltaTime);
}
// Handling the player entering the orbit. Here's where I inverse the up direction of the player. Also stopping any kind of force or rotation
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Planet"))
{
if (!isOrbiting)
score++;
planet = other.gameObject;
isOrbiting = true;
if (score > 0)
{
_rb.velocity = Vector2.zero;
_rb.angularVelocity = 0f;
_rb.rotation = 0f;
transform.up = transform.up * -1;
}
}
}
Use Quaternion.LookRotation to set the player's up to be facing away from the planet and its forward to be world forward (away from camera):
static void SetPlayerUp(Transform player, Transform planet)
{
player.rotation = Quaternion.LookRotation(Vector3.forward,
player.position - planet.position);
}
Consider calling this instead of _rb.rotation = 0f; and transform.up = transform.up * -1;
I have the following code for a simple 2d game. The game is lit by a directional light at the moment, which lights both the background and the player.
public class BlockSpawner : MonoBehaviour
{
public GameObject blockPrefab; // a purple cube
public Vector2 spawnSizeMinMax;
private double _secondsBetweenSpawns = 0.5;
private float _nextSpawnTime;
private void Update()
{
if (Time.time > _nextSpawnTime)
{
_nextSpawnTime = (float) (Time.time + _secondsBetweenSpawns);
float spawnSize = Random.Range(spawnSizeMinMax.x, spawnSizeMinMax.y);
Vector3 spawnPosition =
new Vector3(
Random.Range(Player.screenHalfWidth - spawnSize, -Player.screenHalfWidth + spawnSize),
Player.screenHalfHeight + spawnSize,
5
);
GameObject block = Instantiate(blockPrefab, spawnPosition, Quaternion.identity);
block.transform.parent = transform;
block.transform.localScale = Vector2.one * spawnSize;
block.transform.Rotate(new Vector3(0, 0, Random.Range(-20, 20)));
}
}
}
When I drag the prefab onto the scene it appears as a 3d red cube. When I use this code to spawn it, it appears as a 2d black square and does not respond to lighting at all. In every other way it behaves as expected.
Is there some way to make it accept light? I've tried everything in the inspector.
Edit: Here are some screenshots
As you noticed, it's because you have a zero component in the scale. You should calculate the local scale so that no component is zero. You can do this by using Vector3.one instead of Vector2.one in your assignment:
block.transform.parent = transform;
block.transform.localScale = Vector3.one * spawnSize;
block.transform.Rotate(new Vector3(0, 0, Random.Range(-20, 20)));
Having a zero-componented scale defies certain assumptions that the lighting calculations have when the engine is determining whether a surface is being hit by light or not.
My Unity project is a 2D Tron kind of like game, where the character moves around at a constant velocity and changes direction to up, down, left, and right while leaving a line in its path. All that is working fine. But I want to be able to collide with them as well as with the walls around the map. I want to achieve this using raycasting collisions. Basically, I want the character to not be able to move towards the direction it was moving if a wall is in front of it. The thing is that I don't really know how to stop the character when this happens.
An example of what I want is this:
Here is my code for the player.
void Start(){
direction = Vector2.down;
}
void Update(){
Move(up, down, left, right);
Collision();
}
void Move(KeyCode up, KeyCode down, KeyCode left, KeyCode right){
position = transform.position;
direction = (Input.GetKeyDown(up) && direction != Vector2.down)?Vector2.up:direction;
direction = (Input.GetKeyDown(down) && direction != Vector2.up)?Vector2.down:direction;
direction = (Input.GetKeyDown(left) && direction != Vector2.right)?Vector2.left:direction;
direction = (Input.GetKeyDown(right) && direction != Vector2.left)?Vector2.right:direction;
speed = (Input.GetKey(KeyCode.LeftShift))?2: 4;
velocity = direction / speed;
position += velocity;
transform.position = position;
Trail trail = Instantiate(trail1, transform.position, Quaternion.identity) as Trail;
trail.color = (speed == 2)?new Color32(247, 118, 34, 255):new Color32(254, 174, 52, 255);
}
void Collision(){
float rayLength = 10;
RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, rayLength, collisionMask);
Debug.DrawRay(transform.position, direction * rayLength, Color.red);
if(hit){
}
}
So far, this draws a ray into the direction the player is moving towards. To put everything into perspective, lets say the player is moving left at a constant speed, and I am not pressing the key. If a wall is in front of the player, it will not be able to go through the wall.