I am doing a dig the mud game. Have 2 mud gameobject(sprite) that need to dig in the correct order. I assign one script for each object. Disable mud2 boxcollider to prevent them from moving until mud 1 is drag to trigger L box collider . But when I try playing, mud2 still can be drag even though mud1 havent trigger L box collider. I also untick the box collider of mud2.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pg7_mud1 : MonoBehaviour
{
private Vector3 screenPoint;
private Vector3 startPosition;
public BoxCollider mud2;
// Start is called before the first frame update
void Start()
{
mud2.enabled = false;
}
// Update is called once per frame
void Update()
{
}
void OnMouseDown()
{
startPosition = this.gameObject.transform.position;
screenPoint = Camera.main.WorldToScreenPoint (gameObject.transform.position);
}
void OnMouseDrag()
{
Debug.Log("can drag");
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint);
this.transform.position = new Vector3(curPosition.x, -5f, curPosition.z);
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.name =="left-area")
{
Debug.Log("touched edge");
mud2.enabled = true;
}
}
You could try the Destroy(object, time) method instead of disabling colliders
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pg7_mud1 : MonoBehaviour
{
private Vector3 screenPoint;
private Vector3 startPosition;
public BoxCollider mud2;
public gameObject mud2obj;
// Start is called before the first frame update
void Start()
{
destroy(mud2);
}
// Update is called once per frame
void Update()
{
}
void OnMouseDown()
{
startPosition = this.gameObject.transform.position;
screenPoint = Camera.main.WorldToScreenPoint (gameObject.transform.position);
}
void OnMouseDrag()
{
Debug.Log("can drag");
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint);
this.transform.position = new Vector3(curPosition.x, -5f, curPosition.z);
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.name =="left-area")
{
Debug.Log("touched edge");
mud2obj.AddComponent(typeof(BoxCollider));
}
}
Related
QUESTION
I'm trying to create a simple object "car" animation in Processing.
My code is:
Car car;
void setup(){
size(800, 600);
background(#818B95);
frameRate(30);
car = new Car(10,10);
}
void draw(){
//refresh background
background(#818B95);
print("-");
car.drawCar();
}
void mouseClicked() {
car.run();
}
public class Car implements Runnable{
private int pos_x, pos_y;
public Car(int pos_x, int pos_y){
this.pos_x = pos_x;
this.pos_y = pos_y;
}
public void drawCar(){
rect(pos_x,pos_y,10,10);
}
public void run(){
while(true){
pos_x += 10;
print("*");
delay(200);
}
}
}
I'm expecting to see the car/rectangle move right when I click the mouse button, but nothing happens.
I've added the two print in order to see if the draw method and my car.run are executed in parallel showing some * and - printed alternately.
What I see is a sequence of - until I click and then only * are printed.
Is it possible that starting a new object thread will stop the main draw cycle?
SOLUTION
This is just a variant of the suggested solution (by Mady Daby) without using threads.
Car car;
void setup(){
size(800, 600);
background(#818B95);
frameRate(30);
car = new Car(10,10);
}
void draw(){
//refresh background
background(#818B95);
print("-");
car.drawCar();
}
void mouseClicked() {
car.moving = true;
}
public class Car{
private int pos_x, pos_y;
boolean moving = false;
public Car(int pos_x, int pos_y){
this.pos_x = pos_x;
this.pos_y = pos_y;
}
public void drawCar(){
rect(pos_x,pos_y,10,10);
//animation
if(moving){
pos_x += 10;
print("*");
}
}
}
You could make the car move right by just introducing a boolean variable to track whether the car is supposed to be moving right moving and then increment pos_x if moving is true. You can also use the clicks to toggle between moving and not moving.
Car car;
void setup() {
size(800, 600);
background(#818B95);
frameRate(30);
car = new Car(10, 10);
}
void draw() {
//refresh background
background(#818B95);
print("-");
car.drawCar();
}
void mouseClicked() {
car.toggleMoving();
}
public class Car implements Runnable {
private int pos_x, pos_y;
private boolean moving = false;
public Car(int pos_x, int pos_y) {
this.pos_x = pos_x;
this.pos_y = pos_y;
}
public void toggleMoving() {
moving = !moving;
}
public void drawCar() {
if (moving) {
this.run();
}
rect(pos_x, pos_y, 10, 10);
}
public void run() {
pos_x += 10;
print("*");
delay(200);
}
}
I want to resize a UI panel with the mouse. I don't know how to do this myself. How can I do this?
Kind of a short question, so I'm not sure if you want anything extremely specific, but this is something I found on the Unity Tutorials Website. Seems to be what you're looking for:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ResizePanel : MonoBehaviour, IPointerDownHandler, IDragHandler {
public Vector2 minSize;
public Vector2 maxSize;
private RectTransform rectTransform;
private Vector2 currentPointerPosition;
private Vector2 previousPointerPosition;
void Awake () {
rectTransform = transform.parent.GetComponent<RectTransform>();
}
public void OnPointerDown (PointerEventData data) {
rectTransform.SetAsLastSibling();
RectTransformUtility.ScreenPointToLocalPointInRectangle (rectTransform, data.position, data.pressEventCamera, out previousPointerPosition);
}
public void OnDrag (PointerEventData data) {
if (rectTransform == null)
return;
Vector2 sizeDelta = rectTransform.sizeDelta;
RectTransformUtility.ScreenPointToLocalPointInRectangle (rectTransform, data.position, data.pressEventCamera, out currentPointerPosition);
Vector2 resizeValue = currentPointerPosition - previousPointerPosition;
sizeDelta += new Vector2 (resizeValue.x, -resizeValue.y);
sizeDelta = new Vector2 (
Mathf.Clamp (sizeDelta.x, minSize.x, maxSize.x),
Mathf.Clamp (sizeDelta.y, minSize.y, maxSize.y)
);
rectTransform.sizeDelta = sizeDelta;
previousPointerPosition = currentPointerPosition;
}
}
I'm trying to add a scoring system to my game. However I get this error whenever I play and the asteroids wont destroy anymore when they collide with either the player or a bullet.
My error message is this:
NullReferenceException: Object reference not set to an instance of an object
DestroyByContact.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/DestroyByContact.cs:47)
I should note that all game objects have the correct tags on them as well.
And some Code:
using UnityEngine;
using System.Collections;
public class DestroyByContact : MonoBehaviour {
public GameObject explosion;
public GameObject playerExplosion;
public int scoreValue;
private GameController gameController;
void start () {
GameObject gameControllerObject = GameObject.FindWithTag ("GameController");
if (gameControllerObject != null) {
gameController = gameControllerObject.GetComponent <GameController> ();
}
if (gameController == null)
{
Debug.Log ("Cannot find 'GameController' script");
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "Boundary") {
return;
}
Instantiate(explosion, transform.position, transform.rotation);
if (other.tag == "Player") {
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
}
gameController.AddScore (scoreValue);
Destroy(other.gameObject);
Destroy(gameObject);
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GameController : MonoBehaviour {
public GameObject[] asteroids;
public Vector3 spawnValues;
public int asteroidCount;
public float spawnWait;
public float startWait;
public float waveWait;
public GUIText scoreText;
private int score;
void Start () {
score = 0;
UpdateScore ();
StartCoroutine (spawnWaves ());
}
IEnumerator spawnWaves () {
yield return new WaitForSeconds (startWait);
while (asteroidCount > 0) {
for (int i = 0; i < asteroidCount; i++) {
GameObject asteroid = asteroids[Random.Range(0, asteroids.Length)];
Vector3 spawnPosition = new Vector3 (spawnValues.x, Random.Range (-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate (asteroid, spawnPosition, spawnRotation);
yield return new WaitForSeconds (spawnWait);
}
yield return new WaitForSeconds (waveWait);
if (asteroidCount <= 95) {
asteroidCount += 5;
}
}
}
public void AddScore (int newScoreValue) {
score += newScoreValue;
UpdateScore ();
}
void UpdateScore () {
scoreText.text = "Score:" + score;
}
}
I'd say that better idea would be to set gameController after Instantiate inside Controller. If I understand it right, your GameController spawns asteroids that have DestroyOnContact attached from prefab/predefined collection?
If so, consider doing that way:
GameController
var go = Instantiate (asteroid, spawnPosition, spawnRotation) as GameObject;
if (destroyable != null)
{
var destroyable = go.GetComponent<DestroyByContact>();
if (destroyable == null)
{
//Something else got instantiated, destroy it as we don't need it here
Destroy(destroyable);
}
else
{
destroyable.gameController = this;
}
}
DestroyOnContact
//just change accessor from private to public
public GameController gameController;
//Get rid of stuff that would set gameController in Start()
//Also check if gameController != null before you call .AddScore()
I have a platformer class that creates a window and spawns platforms and a "character". It uses another class platform to make platforms. The character is supposed to jump up and land on the platforms. I use the getBounds and getTopY functions for collision detection but they only work for the first platform. How can i get them to work for multiple platforms?
public class Platformer extends JPanel {
Platform platform = new Platform(this);
Character character = new Character(this);
public Platformer() {
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
character.keyTyped(e);
}
#Override
public void keyReleased(KeyEvent e) {
character.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
character.keyPressed(e);
}
});
setFocusable(true);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
platform.Location(150,200);
platform.paint(g2d);
platform.Location(200,120);
platform.paint(g2d);
character.paint(g2d);
}
private void move(){
character.move();
}
public static void main(String args[]){
JFrame frame = new JFrame("Mini Tennis");
//create new game
Platformer platformer = new Platformer();
//add game
frame.add(platformer);
//size
frame.setSize(400, 400);
frame.setVisible(true);
//set close condition
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
platformer.move();
platformer.repaint();
try {
Thread.sleep(10);//sleep for 10 sec
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
public class Platform {
private static final int Height = 10;
private static final int Width = 60;
int x;
int Y;
private Platformer platformer;
public Platform(Platformer platformer) {
this.platformer = platformer;
}
public void Location(int xin, int yin) {
x = xin;
Y = yin;
}
public void paint(Graphics2D g) {
g.fillRect(x, Y, Width, Height);
}
public Rectangle getBounds() {
return new Rectangle(x, Y, Width, Height);
}
public int getTopPlat() {
return Y;
}
}
Actually you have only one platform. And you draw this platform twice in different places (paint function in Platformer):
platform.Location(150,200);
platform.paint(g2d);
platform.Location(200,120);
platform.paint(g2d);
Therefore I suppose you handle only one platform (with coordinates 200 and 120). You must keep all of your platforms and handle each of them separately.
So basically I'm trying to figure out how to implement rectangles with in a class around each bullet I fire. It's a missile command type game. What I can't figure out is WHERE I would declare the Rectangle and how I would pass it to the game.
Here the code for my rocket class...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ShootingRocket
{
public class Rocket
{
public Texture2D DrawTexture { get; set; }
public Vector2 Position { get; set; }
public Vector2 Direction { get; set; }
public float Rotation { get; set; }
public float Speed { get; set; }
public bool IsShooting { get; set; }
int timeBetweenShots = 100;
int shotTimer = 0;
public Rocket(Texture2D texture, Vector2 position, Vector2 direction, float rotation, float Speed)
{
this.DrawTexture = texture;
this.Position = position;
this.Direction = direction;
this.Rotation = rotation;
this.Speed = Speed;
this.IsShooting = false;
}
public void Update(GameTime gameTime)
{
this.Position += Direction * Speed;
if (IsShooting)
{
shotTimer += gameTime.ElapsedGameTime.Milliseconds;
if (shotTimer > timeBetweenShots)
{
shotTimer = 0;
ProjectileManager.AddBullet(this.Position, this.Direction, 12, 2000, BulletType.Player);
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(
this.DrawTexture,
this.Position,
null,
Color.White,
this.Rotation,
new Vector2(
this.DrawTexture.Width / 2,
this.DrawTexture.Height / 2),
1.0f,
SpriteEffects.None,
1.0f);
Here is the code for my bullet class...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ShootingRocket
{
public enum BulletType { Player, Enemy }
public class Bullet
{
public BulletType Type { get; set; }
public Texture2D DrawTexture { get; set; }
public Vector2 Position { get; set; }
public Vector2 Direction { get; set; }
public float Speed { get; set; }
public int ActiveTime { get; set; }
public int TotalActiveTime { get; set; }
public Bullet(Texture2D texture, Vector2 position, Vector2 direction, float speed, int activeTime, BulletType type)
{
this.DrawTexture = texture;
this.Position = position;
this.Direction = direction;
this.Speed = speed;
this.ActiveTime = activeTime;
this.Type = type;
this.TotalActiveTime = 0;
}
public void Update(GameTime gameTime)
{
this.Position += Direction * Speed;
this.TotalActiveTime += gameTime.ElapsedGameTime.Milliseconds;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(
DrawTexture,
Position,
null,
Color.White,
0f,
new Vector2(
DrawTexture.Width / 2,
DrawTexture.Height / 2),
1.0f,
SpriteEffects.None,
0.8f);
}
}
}
And last but not least my Projectile Manager class...
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace ShootingRocket
{
public class ProjectileManager : DrawableGameComponent
{
static List<Bullet> bullets = new List<Bullet>();
static Texture2D playerBulletTexture;
SpriteBatch spriteBatch;
public ProjectileManager(Game game, SpriteBatch spriteBatch)
: base(game)
{
game.Components.Add(this);
playerBulletTexture = game.Content.Load<Texture2D>("Bullet");
this.spriteBatch = spriteBatch;
}
public override void Update(GameTime gameTime)
{
for(int i = 0; i < bullets.Count; i++)
{
bullets[i].Update(gameTime);
if (bullets[i].TotalActiveTime > bullets[i].ActiveTime)
bullets.RemoveAt(i);
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
foreach (Bullet b in bullets)
{
b.Draw(spriteBatch);
}
base.Draw(gameTime);
}
public static void AddBullet(Vector2 position, Vector2 direction, float speed, int activeTime, BulletType type)
{
bullets.Add(new Bullet(playerBulletTexture, position, direction, speed, activeTime, type));
}
}
}
any help is GREATLY appreciated!
public Rectangle collisionRec {get; private set;}
Then in the update method of the bullet you update the rectangle coordinates.
collisionRec = new Rectangle(position.X, position.Y, spriteWidth, spriteHeight);
You are probably maintaining a list of all those bullets in game1 or somewhere.
foreach (Bullet b in bulletList)
{
if (b.collisionRec.Intersects(someOtherRec))
{
//Do some stuff.
}
}