Unity Making a Board - unity3d

i'm trying to make a board, that have 12 site. i tried to detect one of them with Overlapsphere, but i'm looking for a method to check the 12 site at the same time. so i can know how many object are in each site. anyone can help ? maybe its possible to create an array of overlapSphere ?
here is the code:enter code here
public int count;
[SerializeField]Vector3 position = new Vector3 (0,0,0);
float radius = 2f;
[SerializeField] public Text counter;
// Start is called before the first frame update
void Start()
{
//detectedball();
}
// Update is called once per frame
void Update()
{
detectedball();
}
void detectedball()
{
Collider[] hitColliders = Physics.OverlapSphere(position, radius);
foreach (var hitCollider in hitColliders)
{
// hitCollider.SendMessage("Detected");
if(gameObject.tag == "Ball")
{
count++;
}
Debug.Log(count);
// counter.text = hitCollider.ToString();
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere( position , radius);
}
}

Related

How to do Damage During Animation When Enemy Enters Range?

2D Top Down style game. I’m trying to figure out how to hit an enemy whenever he enters the range of my attack point and get hit every, say, 3 frames if he is still within my attack point. here's my script.
public Animator animator;
public Transform AttackPoint;
public float attackRange = 0.5f;
public LayerMask enemyLayers;
public int attackDamage = 40;
public float attackRate = 1f;
float nextAttackTime = 0f;
// Update is called once per frame
void Update()
{
if(Time.time >= nextAttackTime)
{
if (Input.GetKeyDown(KeyCode.Space))
{
Attack();
nextAttackTime = Time.time + 1f / attackRate;
}
}
}
void Attack()
{
animator.SetTrigger("Attack");
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, attackRange, enemyLayers);
foreach(Collider2D enemy in hitEnemies)
{
enemy.GetComponent<Enemy>().TakeDamage(attackDamage);
}
}
void OnDrawGizmosSelected()
{
if (AttackPoint == null)
return;
Gizmos.DrawWireSphere(AttackPoint.position, attackRange);
}
foreach enemys and check distance with you , and attack it.
and you need a Manager to handle all enemys.
List<Transform> enemys = new List<Transform>();
public void Update()
{
for (int i = 0; i < enemys.Count; i++)
{
float distance = Vector3.Distance(enemys[i].position, transform.position);
if (distance < 10)// in range
{
//todo attack
}
}
}

How can I drag the mouse on a map to navigate it?

I am making a map game in unity. I want to drag the mouse on the map resulting in the player viewing different areas of the map (yes, like Hears of Iron IV). I have tried using the 'onDrag' method but I can not find the proper code for it. Can someone please link some documentation or required code for this method?
Thank you.
If you want to change camera position you can simply do it with this code:
public float dragSpeed = 2;
private Vector3 dragOrigin;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dragOrigin = Input.mousePosition;
return;
}
if (!Input.GetMouseButton(0)) return;
Vector3 pos = Camera.main.ScreenToViewportPoint(dragOrigin - Input.mousePosition);
Vector3 move = new Vector3(pos.x * dragSpeed, 0, pos.y * dragSpeed);
transform.Translate(move, Space.World);
}
With this, you can start and do other things.
If you want to move the map instead of the camera you can also try :
private bool isDragging;
public void OnMouseDown()
{
isDragging = true;
}
public void OnMouseUp()
{
isDragging = false;
}
void Update()
{
if (isDragging) {
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
transform.Translate(mousePosition);
}
}
this work as Drag and Drop any 2d objects in unity.
the other answer does not work since the map should also move while button is held.. here is the fix
public float dragSpeed = 2;
private Vector3 dragOrigin;
private bool dragStarted = false;
if (Input.GetMouseButtonDown(1))
{
dragOrigin = Input.mousePosition;
dragStarted = true;
}
if (Input.GetMouseButtonUp(1))
{
dragStarted = false;
return;
}
if (dragStarted)
{
Vector3 pos = main_camera.ScreenToViewportPoint(dragOrigin - Input.mousePosition);
Vector3 move = new Vector3(pos.x * dragSpeed, 0, pos.y * dragSpeed);
main_camera.transform.Translate(move, Space.World);
}
this also assumes your camera is pointed downwards or facing north..

Unity: Touch Delay is too high

I want to make a game, where you can throw items in 2D via drag and drop. This works fine, but the tracking of grabbing them is very bad. If I touch them in the top half the tracking won't or barely work.
Are there other methods to prevent this?
public class DropsBehaviour : MonoBehaviour {
//Declaring Variables
public int force = 10;
float maxSpeedPreset = 5;
float maxSpeed = 5;
float MaxThrowSpeed = 8;
GameManager gm;
Rigidbody rig;
Camera cam;
bool selected = false;
bool once = false;
void Start() {
gm = GameManager.FindMe();
rig = GetComponent<Rigidbody>();
cam = Camera.main;
}
void Update() {
if (selected) {
rig.AddForce((cam.ScreenToWorldPoint(Input.mousePosition) - transform.position) * force);
rig.velocity = Vector3.zero;
} else {
if (!once) {
maxSpeed = maxSpeedPreset * gm.gameSpeed;
rig.velocity = new Vector3(Mathf.Clamp(rig.velocity.x, -maxSpeed, maxSpeed), Mathf.Clamp(rig.velocity.y, -maxSpeed, maxSpeed), Mathf.Clamp(rig.velocity.z, -maxSpeed, maxSpeed));
} else {
maxSpeed = maxSpeedPreset;
rig.velocity = new Vector3(Mathf.Clamp(rig.velocity.x, -MaxThrowSpeed, MaxThrowSpeed), Mathf.Clamp(rig.velocity.y, -MaxThrowSpeed, MaxThrowSpeed), Mathf.Clamp(rig.velocity.z, -MaxThrowSpeed, MaxThrowSpeed));
}
}
}
void OnMouseDown() {
if (tag != "NoInteract") {
selected = true;
once = true;
}
}
void OnMouseUp() {
selected = false;
}
}
I see quite a few issues in the code snippet you posted that could cause stuttering.
First, if you are making something in 2D, it's recommended to use Rigidbody2D and Collider2D.
Then, you shouldn't edit a rigidbody's velocity by hand, as stated in the doc. That's what add force is made for.
When updating anything related to physics, you should do it in FixedUpdate, not Update.
I assume you also forgot to put " once = false " on the first pass ? Really not sure about this one.
I edited your script following the points stated before, while keeping the rigidbody 3D. I dind't tested it, but hopefully it will correct the weird drag behavior you're experiencing! (note that I removed the GameManager part since i can't know what it does)
public class DropsBehaviour : MonoBehaviour
{
public int force = 10;
private const float MaxSpeedPreset = 5;
private float _maxSpeed = 5;
private const float MaxThrowSpeed = 8;
private Rigidbody _rig;
private Camera _cam;
private bool _selected;
private bool _once;
private Vector3 _targetVelocity;
private void Start()
{
_rig = GetComponent<Rigidbody>();
_cam = Camera.main;
}
private void Update()
{
if (_selected) return;
if (!_once)
{
_maxSpeed = MaxSpeedPreset * 10;
_targetVelocity = new Vector3(Mathf.Clamp(_rig.velocity.x, -_maxSpeed, _maxSpeed),
Mathf.Clamp(_rig.velocity.y, -_maxSpeed, _maxSpeed),
Mathf.Clamp(_rig.velocity.z, -_maxSpeed, _maxSpeed));
}
else
{
_maxSpeed = MaxSpeedPreset;
_targetVelocity = new Vector3(Mathf.Clamp(_rig.velocity.x, -MaxThrowSpeed, MaxThrowSpeed),
Mathf.Clamp(_rig.velocity.y, -MaxThrowSpeed, MaxThrowSpeed),
Mathf.Clamp(_rig.velocity.z, -MaxThrowSpeed, MaxThrowSpeed));
_once = false; //Dunno if it's intended or not ?
}
}
private void FixedUpdate()
{
if (_selected)
{
_rig.AddForce((_cam.ScreenToWorldPoint(Input.mousePosition) - transform.position) * force);
_rig.velocity = Vector3.zero;
return;
}
var velocity = _rig.velocity;
var velocityChange = _targetVelocity - velocity;
_rig.AddForce(velocityChange, ForceMode.VelocityChange);
}
private void OnMouseDown()
{
if (CompareTag("NoInteract")) return;
_selected = true;
_once = true;
}
private void OnMouseUp()
{
_selected = false;
}
}
On a side note, I personnaly don't like tags, I would use a LayerMask instead since it's somewhat related to physics. I'd probably replace the OnMouse events with a Raycast too, that way you would have a lot more control on what is happening on the physic side.

Spring Joint 2D (maybe) causing transform.position errors

I know the title might be misleading after you see what is the problem, but I really don't know how to name this issue.
The first picture shows the problem.
The white line shows the distance between the player and the gameobject called hook. The blue sprite sphere close to the hook is the SpringJoint2D.connectedBody.
They both (the white line and the blue sprite) are working with the same value: hook.transform.position.
Here is the code snippets which I believe are causing problems or at least reveal the most:
SpringJoint2D snippet:
if (Input.GetMouseButtonDown(0))
{
hook = FindClosestObject(radius, "Hook");
if(hook != null)
{
joint.enabled = true;
joint.connectedBody = hook;
joint.connectedAnchor = hook.transform.position;
Debug.Log("Click.");
Debug.Log(hook);
}
}
if (Input.GetMouseButtonUp(0))
{
joint.enabled = false;
joint.connectedBody = null;
}
Debug.DrawLine snippet:
if (hook != null)
{
joint.distance = Vector3.Distance(hook.transform.position, transform.position) / 2;
Debug.DrawLine(transform.position, hook.transform.position);
}
And here is the whole code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerScript : MonoBehaviour
{
public float radius;
private SpringJoint2D joint;
private Rigidbody2D hook = new Rigidbody2D();
// Start is called before the first frame update
void Start()
{
joint = GetComponent<SpringJoint2D>();
}
// Update is called once per frame
void Update()
{
//touch.phase == TouchPhase.Began
if (Input.GetMouseButtonDown(0))
{
hook = FindClosestObject(radius, "Hook");
if(hook != null)
{
joint.enabled = true;
joint.connectedBody = hook;
joint.connectedAnchor = hook.transform.position;
Debug.Log("Click.");
Debug.Log(hook);
}
}
if (Input.GetMouseButtonUp(0))
{
joint.enabled = false;
joint.connectedBody = null;
}
//foreach (Touch touch in Input.touches)
//{
//}
if (hook != null)
{
joint.distance = Vector3.Distance(hook.transform.position, transform.position) / 2;
Debug.DrawLine(transform.position, hook.transform.position);
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(transform.position, radius);
if (hook != null)
Gizmos.DrawLine(transform.position, hook.transform.position);
}
public Rigidbody2D FindClosestObject(float radius, string tag)
{
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag(tag);
Rigidbody2D closest = null;
float distance = radius;
Vector3 position = transform.position;
foreach (GameObject go in gos)
{
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance)
{
closest = go.GetComponent<Rigidbody2D>();
distance = curDistance;
}
}
return closest;
}
}
Ah, I was just stupid.
There is no need to assign the connectedAnchor if you also asign the connectedRigidbody2D
The connectedAnchor is the offset from the connectedRigidbody2D's position...

Make objects between camera and character transparent

I'm working on a script for my camera to make objects between itself and the character transparent.
I managed to make it work with RayCast however I don't know how to restablish objects alpha value after they escape the ray.
This is my current code:
private void XRay() {
float characterDistance = Vector3.Distance(transform.position, GameObject.Find("Character").transform.position);
Vector3 fwd = transform.TransformDirection(Vector3.forward);
RaycastHit hit;
if (Physics.Raycast(transform.position, fwd, out hit, characterDistance)) {
// Add transparence
Color color = hit.transform.gameObject.renderer.material.color;
color.a = 0.5f;
hit.transform.gameObject.renderer.material.SetColor("_Color", color);
}
}
This is my final code. Note it only makes transparent one object at a time, but the same implementation can easily be done with RaycastAll and using an array for oldHits.
public class Camara : MonoBehaviour {
RaycastHit oldHit;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void FixedUpdate() {
XRay ();
}
// Hacer a los objetos que interfieran con la vision transparentes
private void XRay() {
float characterDistance = Vector3.Distance(transform.position, GameObject.Find("Character").transform.position);
Vector3 fwd = transform.TransformDirection(Vector3.forward);
RaycastHit hit;
if (Physics.Raycast(transform.position, fwd, out hit, characterDistance)) {
if(oldHit.transform) {
// Add transparence
Color colorA = oldHit.transform.gameObject.renderer.material.color;
colorA.a = 1f;
oldHit.transform.gameObject.renderer.material.SetColor("_Color", colorA);
}
// Add transparence
Color colorB = hit.transform.gameObject.renderer.material.color;
colorB.a = 0.5f;
hit.transform.gameObject.renderer.material.SetColor("_Color", colorB);
// Save hit
oldHit = hit;
}
}
}
I did attach this script to my simple camera following the player. It might help you.
It can actually manage more than one obstructing the view and also you see I pass it a mask which I target with its name instead of checking for the collider name tag. Have fun.
using UnityEngine;
public class followPlayer : MonoBehaviour
{
public Transform player;
public Vector3 offset;
public Transform[] obstructions;
private int oldHitsNumber;
void Start()
{
oldHitsNumber = 0;
}
private void LateUpdate()
{
viewObstructed();
}
void Update()
{
transform.position = player.TransformPoint(offset);
transform.LookAt(player);
}
void viewObstructed()
{
float characterDistance = Vector3.Distance(transform.position, player.transform.position);
int layerNumber = LayerMask.NameToLayer("Walls");
int layerMask = 1 << layerNumber;
RaycastHit[] hits = Physics.RaycastAll(transform.position, player.position - transform.position, characterDistance, layerMask);
if (hits.Length > 0)
{ // Means that some stuff is blocking the view
int newHits = hits.Length - oldHitsNumber;
if (obstructions != null && obstructions.Length > 0 && newHits < 0)
{
// Repaint all the previous obstructions. Because some of the stuff might be not blocking anymore
for (int i = 0; i < obstructions.Length; i++)
{
obstructions[i].gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
}
obstructions = new Transform[hits.Length];
// Hide the current obstructions
for (int i = 0; i < hits.Length; i++)
{
Transform obstruction = hits[i].transform;
obstruction.gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
obstructions[i] = obstruction;
}
oldHitsNumber = hits.Length;
}
else
{ // Mean that no more stuff is blocking the view and sometimes all the stuff is not blocking as the same time
if (obstructions != null && obstructions.Length > 0)
{
for (int i = 0; i < obstructions.Length; i++)
{
obstructions[i].gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
oldHitsNumber = 0;
obstructions = null;
}
}
}
}