How do I detect if a sprite is overlapping any background sprite? - c#

I want to detect if an empty gameobject is between a sprite which I've drawn and the camera.
Background objects are tagged "Background" and are in the layer "background".
Currently, the Debug.log statement always says "Does not detect background". I've tried switching the direction of the raycast from back to forward several times and that didn't fix it. The gameobject shooting the ray has a z position of -1, the sprite has a z position of 0. The sprite has a 2D box collider on it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoomMaker : MonoBehaviour
{
public float speed = 5;
public float distance = 5;
public Transform horse;
public Transform carriage;
void Update()
{
transform.Translate(Vector2.right * speed * Time.deltaTime);
RaycastHit2D backgroundInfo = Physics2D.Raycast(horse.position, Vector3.forward, distance);
if (backgroundInfo)
{
Debug.Log("DETECTSBACKGROUND");
}
else
{
Debug.Log("Does not detect Background");
//it always displays this one, it never displays the other debug.log
}
}
}

Consider using Physics2D.OverlapPointAll instead of a raycast.
This will require that background sprites have Collider2D components on their gameobjects, their gameobjects be tagged Background and be on the background layer.
I advise having the background layer ignore collisions with everything. See the physics 2d options documentation for more information on how to do that.
Here's what the code could look like:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoomMaker : MonoBehaviour
{
public float speed = 5;
public float distance = 5;
public Transform horse;
public Transform carriage;
void FixedUpdate() // otherwise, visual lag can make for inconsistent collision checking.
{
transform.Translate(Vector2.right * speed * Time.deltaTime);
Collider2D[] cols = Physics2D.OverlapPointAll(
Vector3.Scale(new Vector3(1,1,0), horse.position), // background at z=0
LayerMask.GetMask("background")); // ignore non background layer objects
Collider2D backgroundCol = null;
for (int i = 0 ; i < cols.Length ; i++) // order of increasing z value
{
if (cols[i].tag == "Background") // may be redundant with layer mask
{
backgroundCol = cols[i];
break;
}
}
if (backgroundCol != null)
{
Debug.Log("DETECTSBACKGROUND: " + backgroundCol.name);
}
else
{
Debug.Log("Does not detect Background");
}
}
}
I tested with this setup:

Related

I am making a space shooter but my bullets keep on going up instead of out and not deleting from the Unity Hierarchy

I am trying to practice making a space shooter in order to build on concepts for my main project, and I am having issues because I have gotten where the bullets fire and follow with the ship but they fire up and never delete from the hierarchy in Unity.
Here is the code for the Controller:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Transform myTransform;
public int playerSpeed = 5;
// Start is called before the first frame update
// Reusable Prefab
public GameObject BulletPrefab;
void Start()
{
myTransform = transform;
// Spawning Point
// Position x = -3, y = -3, z = -1
myTransform.position = new Vector3(-3, -3, -1);
}
// Update is called once per frame
void Update()
{
// Movement (left / right) and speed
myTransform.Translate(Vector3.right * playerSpeed * Input.GetAxis("Horizontal") * Time.deltaTime);
// Make the player wrap. If the player is at x = -10
// then it should appear at x = 10 etc.
// If it is positioned at 10, then it wraps to -10
if (myTransform.position.x > 10)
{
myTransform.position = new Vector3(-10, myTransform.position.y, myTransform.position.z);
}
else if (myTransform.position.x < -10)
{
myTransform.position = new Vector3(10, myTransform.position.y, myTransform.position.z);
}
// Space to fire!
// If the player presses space, the ship shoots.
if (Input.GetKeyDown(KeyCode.Space))
{
// Set position of the prefab
Vector3 position = new Vector3(myTransform.position.x, myTransform.position.y - 2, myTransform.position.z);
// Fire!
Instantiate(BulletPrefab, position, Quaternion.identity);
}
}
}
and here is the one for the Bullet prefab:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
public int mySpeed = 50;
private Transform myTransform;
// Start is called before the first frame update
void Start()
{
myTransform = transform;
}
// Update is called once per frame
void Update()
{
// Shooting animation
myTransform.Translate(Vector3.up * mySpeed * Time.deltaTime);
if (myTransform.position.z > 20)
{
DestroyObject(gameObject);
}
}
}
Not sure what I am doing. The bullet has gravity unchecked & is kinematic checked.
Player is positioned at -3, -1, -3.
Why your object isn't being deleted is probably because you are checking its position along the z-axis when you are only moving it along the y-axis. The destroy never runs since your bullet's z position is static and always under 20:
// Shooting animation
myTransform.Translate(Vector3.up * mySpeed * Time.deltaTime);
if (myTransform.position.z > 20)
{
DestroyObject(gameObject);
}
Either you can change the if statement to check along the y-axis or move the bullet along the z-axis, which one you want I cant really say since I don't really understand which direction you want the bullet to travel in.
Also, I don't know if it would cause any problems but DestroyObject has been replaced by Destroy().

Object spawning itself when other object is close enough

How can I make the water in my game (picture below) clone itself and put the clone right next to itself, when another object (the player) is close enough?
Scene:scene
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Paralax : MonoBehaviour
{
// The player
public Transform player;
// The distance from the player needed to copy itself
public float distanceToSpawn = 30f;
// The object
public Transform trans;
bool alreadySpawned;
private void Update()
{
if(!alreadySpawned)
{
// Getting the distance between
float dst = Mathf.Abs(player.position.x - transform.position.x);
if (dst < distanceToSpawn)
{
Transform newTrans = trans;
newTrans.position = (transform.position - new Vector3(/* negative width of the water so it copies itself to the left*/-15.72f, 0f, 0f));
Instantiate(gameObject, newTrans);
alreadySpawned = true;
}
}
}
}
But for some reason the water I placed in the scene is just getting away from the player, and not copying itself. Can anyone help me?
It sounds like trans was maybe the same as transform and therefore you move this very same object away before you spawn a new clone of it as a child.
You would probably rather simply do
var newObj = Instantiate(gameObject, transform);
newObj.transform.position = transform.position + Vector3.left * 15.72f;

Unity3D FollowCam not following player vehicle

I have a garage that gives the option for the player to select the car he wants to take to the race, the problem is the camera doesn't attach to the when it's sent.
The follow camera is using the standard unity assets.
Garage code(This code loads the car into the map):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class LoadCharacter : MonoBehaviour
{
public GameObject[] characterPrefabs;
public Transform spawnPoint;
//public TMP_Text label;
void Start()
{
int selectedCharacter = PlayerPrefs.GetInt("selectedCharacter");
GameObject prefab = characterPrefabs[selectedCharacter];
GameObject clone = Instantiate(prefab, spawnPoint.position, Quaternion.identity);
//label.text = prefab.name;
}
}
Camera code:
using System;
using UnityEngine;
#if UNITY_EDITOR
#endif
namespace UnityStandardAssets.Cameras
{
[ExecuteInEditMode]
public class AutoCam : PivotBasedCameraRig
{
[SerializeField] private float m_MoveSpeed = 3; // How fast the rig will move to keep up with target's position
[SerializeField] private float m_TurnSpeed = 1; // How fast the rig will turn to keep up with target's rotation
[SerializeField] private float m_RollSpeed = 0.2f;// How fast the rig will roll (around Z axis) to match target's roll.
[SerializeField] private bool m_FollowVelocity = false;// Whether the rig will rotate in the direction of the target's velocity.
[SerializeField] private bool m_FollowTilt = true; // Whether the rig will tilt (around X axis) with the target.
[SerializeField] private float m_SpinTurnLimit = 90;// The threshold beyond which the camera stops following the target's rotation. (used in situations where a car spins out, for example)
[SerializeField] private float m_TargetVelocityLowerLimit = 4f;// the minimum velocity above which the camera turns towards the object's velocity. Below this we use the object's forward direction.
[SerializeField] private float m_SmoothTurnTime = 0.2f; // the smoothing for the camera's rotation
private float m_LastFlatAngle; // The relative angle of the target and the rig from the previous frame.
private float m_CurrentTurnAmount; // How much to turn the camera
private float m_TurnSpeedVelocityChange; // The change in the turn speed velocity
private Vector3 m_RollUp = Vector3.up;// The roll of the camera around the z axis ( generally this will always just be up )
protected override void FollowTarget(float deltaTime)
{
// if no target, or no time passed then we quit early, as there is nothing to do
if (!(deltaTime > 0) || m_Target == null)
{
return;
}
// initialise some vars, we'll be modifying these in a moment
var targetForward = m_Target.forward;
var targetUp = m_Target.up;
if (m_FollowVelocity && Application.isPlaying)
{
// in follow velocity mode, the camera's rotation is aligned towards the object's velocity direction
// but only if the object is traveling faster than a given threshold.
if (targetRigidbody.velocity.magnitude > m_TargetVelocityLowerLimit)
{
// velocity is high enough, so we'll use the target's velocty
targetForward = targetRigidbody.velocity.normalized;
targetUp = Vector3.up;
}
else
{
targetUp = Vector3.up;
}
m_CurrentTurnAmount = Mathf.SmoothDamp(m_CurrentTurnAmount, 1, ref m_TurnSpeedVelocityChange, m_SmoothTurnTime);
}
else
{
// we're in 'follow rotation' mode, where the camera rig's rotation follows the object's rotation.
// This section allows the camera to stop following the target's rotation when the target is spinning too fast.
// eg when a car has been knocked into a spin. The camera will resume following the rotation
// of the target when the target's angular velocity slows below the threshold.
var currentFlatAngle = Mathf.Atan2(targetForward.x, targetForward.z)*Mathf.Rad2Deg;
if (m_SpinTurnLimit > 0)
{
var targetSpinSpeed = Mathf.Abs(Mathf.DeltaAngle(m_LastFlatAngle, currentFlatAngle))/deltaTime;
var desiredTurnAmount = Mathf.InverseLerp(m_SpinTurnLimit, m_SpinTurnLimit*0.75f, targetSpinSpeed);
var turnReactSpeed = (m_CurrentTurnAmount > desiredTurnAmount ? .1f : 1f);
if (Application.isPlaying)
{
m_CurrentTurnAmount = Mathf.SmoothDamp(m_CurrentTurnAmount, desiredTurnAmount,
ref m_TurnSpeedVelocityChange, turnReactSpeed);
}
else
{
// for editor mode, smoothdamp won't work because it uses deltaTime internally
m_CurrentTurnAmount = desiredTurnAmount;
}
}
else
{
m_CurrentTurnAmount = 1;
}
m_LastFlatAngle = currentFlatAngle;
}
// camera position moves towards target position:
transform.position = Vector3.Lerp(transform.position, m_Target.position, deltaTime*m_MoveSpeed);
// camera's rotation is split into two parts, which can have independend speed settings:
// rotating towards the target's forward direction (which encompasses its 'yaw' and 'pitch')
if (!m_FollowTilt)
{
targetForward.y = 0;
if (targetForward.sqrMagnitude < float.Epsilon)
{
targetForward = transform.forward;
}
}
var rollRotation = Quaternion.LookRotation(targetForward, m_RollUp);
// and aligning with the target object's up direction (i.e. its 'roll')
m_RollUp = m_RollSpeed > 0 ? Vector3.Slerp(m_RollUp, targetUp, m_RollSpeed*deltaTime) : Vector3.up;
transform.rotation = Quaternion.Lerp(transform.rotation, rollRotation, m_TurnSpeed*m_CurrentTurnAmount*deltaTime);
}
}
}
This are the cars that the map gets from the selection
This is the follow cam
This is what happens when the player chooses the car, it switches places with an empty object
The only way to follow is if I go in the editor and manually drag the car into the follow
Edit: I found a way to work around it, anyone wondering you just have to make a prefab with the car and camera.

How to shoot ball to Touch X position Unity 3D?

I have a ball on a ground, and when touching the screen I want to shoot it to the X position of the Touch. Do you have any suggestions?
This is the code I have so far:
public Rigidbody Ball;
public float Speed = 50f;
void FixedUpdate () {
if(ClickDone == false){
if (Input.GetMouseButton(0)){
ClickDone = true;
Ball.velocity = transform.forward * Speed;
}
}
}
here is your new code :
using UnityEngine;
public class GoToTouch : MonoBehaviour
{
public Camera cam;//put your main camera here
public float speed;//Speed of movement
Vector3 LastTouch;
void Start()
{
LastTouch = Vector3.zero;
}
void Update()
{
//We check for new touches etch frame
if (Input.touchCount> 0)
LastTouch = Input.touches[0].rawPosition;
//We move towards the last touch
if(LastTouch != Vector3.zero)transform.position=
Vector3.Lerp(transform.position,cam.ScreenToWorldPoint(LastTouch),speed*Time.DeltaTime);
}
}
what is important for you to look at is the
ScreenToWorldPoint function LastTouch holds the actual pixel the user touched
after ScreenToWorldPoint you get the position that the pixel he touched represent in the
world. Good luck learning !

Unity 5 How to fire a bullet

I have been working on this code for a while and I just cant seem to figure it out. When I click in the game instead of going to the mouse posistion it throws my bullets far away usually from anywhere to 100 to 300.
using UnityEngine;
using System.Collections;
public class Shoot : MonoBehaviour {
public GameObject Player;
public GameObject Bullet;
void Update()
{
bool Shot = false;
if(Input.GetMouseDown(0) && Shot == false)
{
Shot = true;
}
if (Shot == true)
{
float x = Player.transform.position.x;
float z = Player.transform.position.z;
Instantiate(Bullet, new Vector3(x, 0.5f, z)), Quaternion.identity);
x = Input.mousePosition.x;
z = Input.mousePosition.z;
}
}
}
This code doesn't make much sense for me; You just instantiate a Gameobject at the last mouse position (which is on you screen, not in the 3D world) and you don't apply any force to it. Please take a look at this thread (you probably want to use the Gun_Physical script).

Categories