I am making a 2D camera follow script where if the player enters a collider it will test if that has the layer "waypoint" and if so the camera will go to the center of the gameobject with that collider in a smooth transition; however, when I try to test if the player is colliding with OnCollisionEnter2D it doesn't execute, I also tried OnTriggerEnter2D and that doesn't work either. I tested each with "is trigger" true, and false, and with a rigidbody set to kinematic. the only thing I haven't tried is adding a rigidbody with kinematic false, but I don't want to go through the trouble of having to make physics not effect the player with kinematic true.
Camera script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamFollow : MonoBehaviour
{
public Transform player;
public Transform playerFrame;
public List<GameObject> waypoints;
private bool hasWaypoints;
private bool inWaypoint;
private int waypointIn;
// Start is called before the first frame update
void Start()
{
hasWaypoints = true;
if (waypoints.Count == 0)
{
hasWaypoints = false;
}
inWaypoint = false;
waypointIn = 0;
}
// Update is called once per frame
void Update()
{
if (hasWaypoints)
{
if (inWaypoint)
Move(waypoints[waypointIn].transform.position);
else
MoveInFrame(player.position);
}
else
{
MoveInFrame(player.position);
}
}
void MoveInFrame(Vector3 moveTo)
{
Vector3 playerFrameRelative = playerFrame.position - transform.position;
transform.position = Vector3.MoveTowards(transform.position, moveTo - playerFrameRelative, 10);
transform.position = new Vector3(transform.position.x, transform.position.y, -10);
}
void Move(Vector3 moveTo)
{
transform.position = Vector3.MoveTowards(transform.position, moveTo, 10);
transform.position = new Vector3(transform.position.x, transform.position.y, -10);
}
public void Coll(Collider2D collision)
{
inWaypoint = true;
waypointIn = waypoints.IndexOf(collision.gameObject);
}
public void setWaypoint(bool b)
{
inWaypoint = b;
}
}
Player script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed = 9.53f;
public float jumpPower = 2.46f;
public float gravity = 0.65f;
public bool startsBackwards;
public GameObject camera;
public LayerMask layerMask;
private float upSpeed;
private int jumps;
private RaycastHit2D hit;
private Vector3 direction;
void Start()
{
if (startsBackwards)
direction = Vector3.left;
else
direction = Vector3.right;
}
void Update()
{
if (jumps < 3)
{
if (Input.GetKeyDown("w") || Input.GetKeyDown("up") || Input.GetKeyDown("space"))
{
upSpeed = jumpPower + gravity;
jumps--;
}
}
transform.Translate(direction * speed * Time.deltaTime);
upSpeed = upSpeed - gravity;
if (upSpeed < 0)
{
hit = Physics2D.BoxCast(transform.position, new Vector2(1, 1), 0, Vector2.down, -upSpeed, layerMask.value);
if (hit)
{
transform.Translate(Vector3.down * hit.distance);
jumps = 0;
upSpeed = 0;
}
else
transform.Translate(Vector3.up * upSpeed);
}
if (upSpeed > 0)
{
//hit = Physics2D.BoxCast(transform.position, new Vector2(1, 1), 0, Vector2.up, upSpeed);
if (false)
transform.Translate(Vector3.up * hit.distance);
else
transform.Translate(Vector3.up * upSpeed);
}
}
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Reverse")
{
if (direction == Vector3.right)
direction = Vector3.left;
else
direction = Vector3.right;
}
if (camera.GetComponent<CamFollow>().waypoints.Contains(collision.gameObject))
camera.GetComponent<CamFollow>().Coll(collision);
else
camera.GetComponent<CamFollow>().setWaypoint(false);
Debug.Log("worked!");
}
}
Help me please!!
Related
So, I want to make it so the player loses control when it collides with an enemy. I already got a thing set up to make the player fly off towards the direction of the collision, but I can't seem to be able to make them lose control. I want input to not register.
Here's my player controller script:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public Rigidbody2D _rigidBody2d;
Animator animatorController;
public float moveSpeed;
public float jumpForce = 1f;
float maxJumpHeight;
bool isOnGround = false;
bool collidedWithEnemy = false;
private void Start()
{
_rigidBody2d = GetComponent<Rigidbody2D>();
animatorController = GetComponent<Animator>();
}
float horizontalInput;
private void Update()
{
if (collidedWithEnemy == false)
{
horizontalInput = Input.GetAxis("Horizontal");
}
// Player movement
MovementMechanics();
// Sprite Flipping
SpriteFlipping();
// Jumping
JumpingMechanics();
// Set Falling Animation
FallingMechanics();
}
void MovementMechanics()
{
if (horizontalInput != 0)
{
transform.Translate(new Vector2(1, 0) * horizontalInput * Time.deltaTime * moveSpeed);
animatorController.SetBool("isMoving", true);
}
else
{
animatorController.SetBool("isMoving", false);
}
}
void SpriteFlipping()
{
if (horizontalInput > 0)
{
transform.localScale = new Vector3(-1, 1, 1);
}
else if (horizontalInput < 0)
{
transform.localScale = new Vector3(1, 1, 1);
}
}
void JumpingMechanics()
{
if (Input.GetKeyDown(KeyCode.Space) && isOnGround)
{
_rigidBody2d.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
isOnGround = false;
animatorController.SetBool("isMoving", false);
animatorController.SetBool("isJumping", true);
animatorController.SetBool("isFalling", false);
}
}
void FallingMechanics()
{
if (_rigidBody2d.velocity.y < 0f)
{
animatorController.SetBool("isFalling", true);
}
else if (_rigidBody2d.velocity.y > 0f)
{
animatorController.SetBool("isFalling", false);
animatorController.SetBool("isJumping", true);
}
}
void OnCollisionEnter2D(Collision2D other)
{
// Avoids Jump Spawn
if (other.gameObject.CompareTag("Ground"))
{
isOnGround = true;
collidedWithEnemy = false;
animatorController.SetBool("isJumping", false);
animatorController.SetBool("isMoving", false);
animatorController.SetBool("isFalling", false);
}
// On Collision With Enemy
if (other.gameObject.CompareTag("Enemy"))
{
collidedWithEnemy = true;
}
}
}
And here's the enemy script:
using UnityEngine;
public class EnemyController : MonoBehaviour
{
Vector2 otherTransform;
Rigidbody2D playerRigidBody2d;
public float impulseForce = 100f;
private void Start()
{
playerRigidBody2d = GameObject.Find("Player").GetComponent<Rigidbody2D>();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
otherTransform = other.gameObject.transform.position;
playerRigidBody2d.AddForce((otherTransform * 1) * impulseForce, ForceMode2D.Impulse);
other.transform.Translate(Vector3.zero);
}
}
}
And here's a little video of whats happening:
https://vimeo.com/709461296
As you can see in the console, the game still registers horizontal input after collision with enemy
(Don't mind the player launching off at lightspeed, thats not my concern here, I can fix that easily)
I'd say the problem is that you don't set horizontalInput to zero if the collision happens. The way you wrote your Update method, it takes the previously assigned value of horizontalInput and processes it.
Add the condition of not colliding with the enemy in MovementMechanics():
if (horizontalInput != 0 && !collidedWithEnemy)
{
// do something..
}
when I was watching on YouTube, tutorials about endless runner on part 2, the game object wouldn't disappear when it hits the player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Obstacle : MonoBehaviour
{
public int damage = 1;
public float speed;
private void Update()
{
transform.Translate(Vector2.left * speed * Time.deltaTime);
}
void onTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("rocket"))
{
//rocket takes damage 1
other.GetComponent<rocket>().health -= damage;
Debug.Log(other.GetComponent<rocket>().health);
Destroy(gameObject);
}
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class rocket : MonoBehaviour
{
private Vector2 targetPos;
public float Yincrement;
public float speed;
public float maxHeight;
public float minHeight;
public int health = 3;
void Update()
{
if (health <= 0)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.UpArrow) && transform.position.y < maxHeight)
{
targetPos = new Vector2(transform.position.x, transform.position.y + Yincrement);
}
else if (Input.GetKeyDown(KeyCode.DownArrow) && transform.position.y > minHeight)
{
targetPos = new Vector2(transform.position.x, transform.position.y - Yincrement);
}
}
}
from this one https://www.youtube.com/watch?v=FVCW5189evI and I'm confused why it didn't work, can someone tell me what is wrong?
if you want to destroy use this, Correct Method to get the game object when collide is: other.gameObject
void onTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("rocket"))
{
//rocket takes damage 1
other.gameObject.GetComponent<rocket>().health -= damage;
Debug.Log(other.gameObject.GetComponent<rocket>().health);
Destory(other.gameObject);
}
}
public class megaStar : MonoBehaviour{
private Rigidbody2D rb;
private Animator _ani;
public bool canAttack = true;
[SerializeField] private Attack _attackObject;
private AudioSource _as;
public checkpoint lastCheckpoint;
public bool isDead = false;
private float _timer = 1.0f;
public float attackTimer = 2.0f;
public GameObject projectile;
public float projectileSpeed = 18.0f;
public Transform projectileAttackPoint;
public float timeDelayForNextShoot = 0.1f;
private float CONST_timeDelayForNextShoot;
// Start is called before the first frame update
void Start(){
CONST_timeDelayForNextShoot = timeDelayForNextShoot;
rb = GetComponent<Rigidbody2D>();
_as = GetComponent<AudioSource>();
_ani = GetComponent<Animator>();
_timer = attackTimer;
}
void Update(){
if (Input.GetKey(KeyCode.W))
{
rb.velocity = new Vector2(0f, 10f);
}
else if (Input.GetKey(KeyCode.S))
{
rb.velocity = new Vector2(0f, -10f);
}
else
{
rb.velocity = new Vector2(0f, 0f);
}
timeDelayForNextShoot -= Time.deltaTime;
if (Input.GetKeyDown(KeyCode.K) && timeDelayForNextShoot <= 0f){
_ani.SetBool("projectileAttack", true);
GameObject go = Instantiate(projectile, projectileAttackPoint.position, projectileAttackPoint.rotation) as GameObject;
go.GetComponent<Rigidbody2D>().velocity = new Vector2(-projectileSpeed, 0.0f);
Destroy(go, 2.0f);
timeDelayForNextShoot = CONST_timeDelayForNextShoot;
canAttack = false;
// new WaitForSeconds(1);
return;
}
}
void FixedUpdate()
{
if (!isDead)
{
Update();
}
else{
rb.velocity = Vector2.zero;
RigidbodyConstraints2D newRB2D = RigidbodyConstraints2D.FreezePositionY;
rb.constraints = newRB2D;
}
}
private void OnCollisionEnter2D(Collision2D collision){
if (collision.gameObject.CompareTag("Enemy"))
{
GetComponent<HitPoints>().TakeDamage(1);
}
}
}
Use SetActive instead of Destroy Function.
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("rocket"))
{
//rocket takes damage 1
other.gameObject.GetComponent<rocket>().health -= damage;
Debug.Log(other.gameObject.GetComponent<rocket>().health);
gameObject.SetActive(false);// it'll Hide GameObject instead of Destroying
// gameObject.SetActive(true);// to show again
}
}
In my game I want to have a floating monster that's attack throws a grenade at the player. My problem is that the grenade only spawns in 0, 0, 0. In my script I make it so that the zombies spawns in on its own location but for some reason that doesn't work. I tried making it spawn by having the spawn location equal new Vector3(100, 100, 100) but it still spawned at 0, 0, 0. I know that the co-routine runs because I put a Debug.Log. Thanks for the help!
Edit #2: I can't have a rigidbody on the script. I have edited the movement script and I have found that no mater what if a rigidbody is added then it will go to 0, 0, 0.
Edit #3: I updated the scripts
Here is my script: (Sorry if the code is bad)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZKAttack_lvl3 : MonoBehaviour
{
public Transform Player;
public float MoveSpeed = 2.0f;
public float InRadius = 10.0f;
public float AttackRange = 15.0f;
private Coroutine hasCourutineRunYet;
public GameObject grenade;
public GameObject FloatingMonster;
private Vector3 FloatingMon;
private Animator anim;
private Rigidbody rigid;
private void Start()
{
anim = GetComponent<Animator>();
Player = GameObject.FindGameObjectsWithTag("Player")[0].transform;
rigid = GetComponent<Rigidbody>();
}
void Update()
{
Player = GameObject.FindGameObjectsWithTag("Player")[0].transform;
transform.LookAt(Player);
float dstSqr = (Player.position - transform.position).sqrMagnitude;
bool inRadius = (dstSqr <= InRadius * InRadius);
bool inAttackRange = (dstSqr <= AttackRange * AttackRange);
anim.SetBool("AttackingPlayer", inAttackRange);
if (inRadius)
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
}
rigid.AddForce(1, 10, 1);
if (inAttackRange)
{
if (hasCourutineRunYet == null)
{
hasCourutineRunYet = StartCoroutine(GrenadeAttack());
}
}
}
IEnumerator GrenadeAttack()
{
FloatingMon = FloatingMonster.transform.position;
GameObject bulletObject = Instantiate(grenade, FloatingMonster.transform.position, Quaternion.identity);
yield return new WaitForSeconds(2.0f);
}
}
Edit: This is the code for the movement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrenadeMovement : MonoBehaviour
{
public float speed = 10f;
public float lifeDuration = 4.0f;
private float lifeTimer;
private Coroutine hasCourutineRunYet;
private Transform Player;
public SphereCollider sphereCollider;
// Use this for initialization
void Start()
{
lifeTimer = lifeDuration;
sphereCollider.enabled = false;
Player = GameObject.FindGameObjectsWithTag("Player")[0].transform;
}
// Update is called once per frame
void Update()
{
lifeTimer -= Time.deltaTime;
if (lifeTimer >= 3f)
{
Player = GameObject.FindGameObjectsWithTag("Player")[0].transform;
transform.LookAt(Player);
transform.position += transform.forward * speed * Time.deltaTime;
}
if (lifeTimer >= 0f)
{
transform.position = speed * transform.up * Time.deltaTime;
transform.position = speed * transform.forward * Time.deltaTime;
}
if (lifeTimer <= 0f)
{
if (hasCourutineRunYet == null)
{
hasCourutineRunYet = StartCoroutine(GrenadeExplosion());
}
}
}
private void OnTriggerEnter(Collider coll)
{
if (coll.gameObject.tag == "Player")
{
if (hasCourutineRunYet == null)
{
hasCourutineRunYet = StartCoroutine(GrenadeExplosion());
}
}
}
IEnumerator GrenadeExplosion()
{
sphereCollider.enabled = true;
yield return new WaitForSeconds(1.0f);
Destroy(gameObject);
}
}
With the help of #ken I figured out that I couldn't use a rigidbody so I changed the insantiation to this: GameObject bulletObject = Instantiate(grenade, FloatingMonster.transform.position, Quaternion.identity);. I then changed the movement script for it to:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrenadeMovement : MonoBehaviour
{
public float speed = 10f;
public float lifeDuration = 4.0f;
private float lifeTimer;
private Coroutine hasCourutineRunYet;
private Transform Player;
public SphereCollider sphereCollider;
public Vector3 velocity;
// Use this for initialization
void Start()
{
lifeTimer = lifeDuration;
sphereCollider.enabled = false;
Player = GameObject.FindGameObjectsWithTag("Player")[0].transform;
}
// Update is called once per frame
void Update()
{
lifeTimer -= Time.deltaTime;
if (lifeTimer >= 2f)
{
Player = GameObject.FindGameObjectsWithTag("Player")[0].transform;
transform.LookAt(Player);
transform.position += transform.forward * 5 * Time.deltaTime;
}
if (lifeTimer >= 0f && lifeTimer <= 2f)
{
transform.position = 9.18f * transform.up * Time.deltaTime;
transform.position = 9.18f * transform.forward * Time.deltaTime;
}
if (lifeTimer <= 0f)
{
if (hasCourutineRunYet == null)
{
hasCourutineRunYet = StartCoroutine(GrenadeExplosion());
}
}
}
private void OnTriggerEnter(Collider coll)
{
if (coll.gameObject.tag == "Player" || coll.gameObject.tag == "Terrain")
{
if (hasCourutineRunYet == null)
{
hasCourutineRunYet = StartCoroutine(GrenadeExplosion());
}
}
}
IEnumerator GrenadeExplosion()
{
sphereCollider.enabled = true;
yield return new WaitForSeconds(1.0f);
Destroy(gameObject);
}
}
Thank you for all your help, I have been trying to fix this all week.
You could set its position in the Instantiate line. Instantiate has several arguments. You can set its position in Instantiate, as well as its rotation and parent.
Set it to this:
IEnumerator GrenadeAttack()
{
GameObject bulletObject = Instantiate(grenade, FloatingMonster.transform.position, Quaternion.identity);
yield return new WaitForSeconds(2.0f);
}
I have both player and ground with colliders 2D and player is supposed to stop on top of ground but instead it stops at the bottom of the ground.
Code
PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
private float moveSpeedStore;
public float speedMultiplier;
public float speedIncreateMilestone;
private float speedIncreateMilestoneStore;
private float speedMilestoneCount;
private float speedMilestoneCountStore;
public float jumpForce;
public float jumpTime;
private float jumpTimeCounter;
private bool stoppedJumping;
private bool canDoubleJump;
private Rigidbody2D myRigidbody;
public bool grounded;
public LayerMask whatIsGround;
public Transform groundCheck;
public float groundCheckRadius;
// private Collider2D myCollider;
private Animator myAnimator;
public GameManager theGameManager;
public AudioSource jumpSound;
public AudioSource deathSound;
// Start is called before the first frame update
void Start()
{
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
jumpTimeCounter = jumpTime;
speedMilestoneCount = speedIncreateMilestone;
moveSpeedStore = moveSpeed;
speedMilestoneCountStore = speedMilestoneCount;
speedIncreateMilestoneStore = speedIncreateMilestone;
stoppedJumping = true;
}
// Update is called once per frame
void Update()
{
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
if(transform.position.x > speedMilestoneCount)
{
speedMilestoneCount += speedIncreateMilestone;
speedIncreateMilestone = speedIncreateMilestone * speedMultiplier;
moveSpeed = moveSpeed * speedMultiplier;
}
myRigidbody.velocity = new Vector2(moveSpeed, myRigidbody.velocity.y);
if(Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0) )
{
if(grounded)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
stoppedJumping = false;
jumpSound.Play();
}
if(!grounded && canDoubleJump)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
jumpTimeCounter = jumpTime;
stoppedJumping = false;
canDoubleJump = false;
jumpSound.Play();
}
}
if((Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0)) && !stoppedJumping)
{
if(jumpTimeCounter > 0)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
jumpTimeCounter -= Time.deltaTime;
}
}
if(Input.GetKeyUp(KeyCode.Space) || Input.GetMouseButtonUp(0))
{
jumpTimeCounter = 0;
stoppedJumping = true;
}
if(grounded)
{
jumpTimeCounter = jumpTime;
canDoubleJump = true;
}
myAnimator.SetFloat("Speed", myRigidbody.velocity.x);
myAnimator.SetBool("Grounded", grounded);
}
void OnCollisionEnter2D(Collision2D other) {
if(other.gameObject.tag == "killbox")
{
theGameManager.RestartGame();
moveSpeed = moveSpeedStore;
speedMilestoneCount = speedMilestoneCountStore;
speedIncreateMilestone = speedIncreateMilestoneStore;
deathSound.Play();
}
}
}
Player settings
Question
What should I do to hold my player on top of ground?
NOTE: it's my first question on unity ever so if you need any sort of code or data please just ask, I try my best to provide you what you need.
Thanks.
It looks like your collider is simply too high. You'll notice that the green box indicating your collider size and position is colliding with the correct spot on the ground. The bottom of it is just touching the top of the ground. You simply need to move the collider down on the player so that the bottom of the green box is at the bottom of the player's sprite.
I'm creating a test game because I'm getting ready to create my first game but I want to make sure I get all the simple mechanics down that my first game will require. One of the mechanics that will be included in the game is picking up items if they are a certain distance to you. Sometimes there might be multiple of the same object in the game, I figured the code would work for all coins however that is just not the case. The Debug.Log() only works on one specific coin, how do I make it so it will fire no matter what coin I'm near?
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour {
//Player Variables
public float moveSpeed;
public float jumpHeight;
public float raycastDistanceGround;
public Text moneyText;
private bool isGrounded;
private Rigidbody _rgb;
private GameObject player;
private GameObject[] coin;
private float distanceToCollectCoin;
private float distanceToCoin;
void Start () {
moveSpeed = 7f;
jumpHeight = 9f;
raycastDistanceGround = 0.5f;
isGrounded = true;
_rgb = GetComponent<Rigidbody>();
player = GameObject.FindGameObjectWithTag("Player");
coin = GameObject.FindGameObjectsWithTag("Coin");
distanceToCollectCoin = 2f;
Cursor.lockState = CursorLockMode.Locked;
}
void FixedUpdate () {
IsGrounding();
Move();
Jump();
SetMoneyText();
NearCoin();
}
//Player Moving Mechanics
void Move() {
var moveHorizontal = Input.GetAxis("Horizontal") * moveSpeed * Time.fixedDeltaTime;
var moveVertical = Input.GetAxis("Vertical") * moveSpeed * Time.fixedDeltaTime;
transform.Translate(moveHorizontal, 0f, moveVertical);
if (Input.GetKeyDown(KeyCode.Escape)) {
Cursor.lockState = CursorLockMode.None;
}
}
//Player Jump Mechanics
void Jump() {
var jump = new Vector3(0f, _rgb.position.y, 0f);
if (Input.GetKey(KeyCode.Space) && isGrounded == true) {
for (float i = 0; i <= jumpHeight; i++) {
jump.y += i;
_rgb.AddForce(jump);
}
}
}
void IsGrounding() {
if (Physics.Raycast(transform.position, Vector3.down, raycastDistanceGround)) {
isGrounded = true;
} else {
isGrounded = false;
}
}
void SetMoneyText() {
moneyText.text = ("Money: " + EconomyController.Money);
}
void NearCoin() {
for (int i = 0; i < coin.Length; i++) {
distanceToCoin = Vector3.Distance(coin[i].transform.position, player.transform.position);
}
if (distanceToCoin < distanceToCollectCoin) {
Debug.Log("Near Coin");
}
}
}
Looks like you just bracketed some stuff wrong. You need to move your if-statement into the for-loop. Right now it's only checking the distance for the last coin in the array.
void NearCoin()
{
for (int i = 0; i < coin.Length; i++)
{
distanceToCoin = Vector3.Distance(coin[i].transform.position, player.transform.position);
if (distanceToCoin < distanceToCollectCoin)
Debug.Log("Near Coin");
}
}