Debug.DrawLine not showing in the GameView - c#

I'm working on a 2D Unity app and I'm encountering some weird behavior.
This code works just fine.
Debug.DrawLine(button1.transform.position, button2.transform.position, Color.green);
When I run the app, I see a green line in the Scene view.
But nothing appears in the Game view when I have the following line.
Physics2D.Linecast(button1.transform.position, button2.transform.position);
I'm confused as to how Unity is able to draw a line between these two buttons, but for some reason, it's just not doing it in the Game view.
Any idea how I'd troubleshoot this?

Just line Serlite said, Physics2D.Linecast is not used to draw a line but to detect if there is an object in the middle of two objects with raycast. It has nothing to do with drawing lines.
As you already know, Debug.DrawLine will only work in the Scene view unless Gizmos is enabled. You can just LineRenderer or the GL functions to draw lines which will work without enabling Gizmos and will also work in a build.
Here is a helper class for drawing line in the Game and Scene view.
public struct LineDrawer
{
private LineRenderer lineRenderer;
private float lineSize;
public LineDrawer(float lineSize = 0.2f)
{
GameObject lineObj = new GameObject("LineObj");
lineRenderer = lineObj.AddComponent<LineRenderer>();
//Particles/Additive
lineRenderer.material = new Material(Shader.Find("Hidden/Internal-Colored"));
this.lineSize = lineSize;
}
private void init(float lineSize = 0.2f)
{
if (lineRenderer == null)
{
GameObject lineObj = new GameObject("LineObj");
lineRenderer = lineObj.AddComponent<LineRenderer>();
//Particles/Additive
lineRenderer.material = new Material(Shader.Find("Hidden/Internal-Colored"));
this.lineSize = lineSize;
}
}
//Draws lines through the provided vertices
public void DrawLineInGameView(Vector3 start, Vector3 end, Color color)
{
if (lineRenderer == null)
{
init(0.2f);
}
//Set color
lineRenderer.startColor = color;
lineRenderer.endColor = color;
//Set width
lineRenderer.startWidth = lineSize;
lineRenderer.endWidth = lineSize;
//Set line count which is 2
lineRenderer.positionCount = 2;
//Set the postion of both two lines
lineRenderer.SetPosition(0, start);
lineRenderer.SetPosition(1, end);
}
public void Destroy()
{
if (lineRenderer != null)
{
UnityEngine.Object.Destroy(lineRenderer.gameObject);
}
}
}
Usage:
LineDrawer lineDrawer;
void Start()
{
lineDrawer = new LineDrawer();
}
void Update()
{
lineDrawer.DrawLineInGameView(Vector3.zero, new Vector3(0, 40, 0f), Color.blue);
}
When done, you can call lineDrawer.Destroy();.

Debug.DrawLine renders a line gizmo into the Scene View.
If you want a line rendered into the Game View, use a Line Renderer Component.
Line Renderer Docs

Related

Unity Tilemaps, Single Tile Collision detection for highlighting Tiles/Cells, strange behaviour

Ive been working for a few days on this problem, trying to create a square grid of tiles, using Unity Tilemaps seems to be the most efficient way, and it has a lot built in already.
I want to highlight the tiles around the player so that he will see what the legal moves are.
I use a second Tilemap for this, on top of the basemap(ground/grass).
The second Tilemap, the highlightsMap is made up of invisible Tiles, which will turn into highlighted Tiles when a Physics.SphereOverlap occurs, or a Physics2D.CircleAll
To detect every Tile, I have added a box collider on an empty object and I made a grid of these colliders on top of the Tilemap grid, so that:
Box Collider at Position (2,4,0) is exactly on top of Tile at Position(2,4,0)
This should be the most straightforward way to handle this, as you can change a Tile, using Tilemap.SetTile(Vector3Int Pos, Tile tile)
The problem is very strange however. The colliders have the correct positional values to be able to reference the tiles exactly underneath them, just through that position data. As explained above, and I have double checked this, the collider empties have the exact same position as the tiles underneath them, no conversion is needed.
The problem is that the tiles are not highlighting around the player as expected, instead a few next to the player are highlighted and others arent, the Physics.OverlapSphere I am using only works on 3D Colliders, which is why I added them as another grid on top of everything.
Using Physics2D.CircleAll, unfortunately does not detect any 2D colliders on the tiles themselves(Sprite, or Grid), not sure if that is intended to work like that anyway.
Collision Grid Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class scr_ColliderGrid : MonoBehaviour
{
public GameObject eCollider;
public Tile invisibleTile;
public Tile highlightTile;
public Tilemap highlightMap;
public int xSize, ySize;
private Vector3Int[] gridArray; // Tilemaps use Vector3Int BUT only use (X, Y, 0) !!!!!!!
private int xC = 0, yC = 0, i = 0;
private Tile[] tiles;
private Vector3Int previous;
private void Start()
{
gridArray = new Vector3Int[xSize * ySize];
tiles = new Tile[xSize * ySize];
GenerateCollisionGrid();
}
private void GenerateCollisionGrid()
{
for (xC = 0; xC < xSize; xC++)
{
for (yC = 0; yC < ySize; yC++)
{
Vector3Int newPos = new Vector3Int(xC, yC, 0); // 2, 4, 0
Vector3Int newColPos = new Vector3Int(xC, yC, 0); // 2, 4, 0 //This used to be different values, but now they are exactly the same.
if (invisibleTile != null)
{
Tile tile = Instantiate(invisibleTile, newPos, Quaternion.identity, transform);
tiles[i] = tile;
GameObject col = Instantiate(eCollider, newColPos, Quaternion.identity, transform);
}
gridArray[i] = newPos;
i++;
}
}
highlightMap.SetTiles(gridArray, tiles);
highlightMap.SetTile(new Vector3Int(2,4,0), highlightTile); // 2,4,0 //Test to see if positions are the same. (collider and tiles)
}
Player Highlight Legal Moves Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class scr_TankMoves : MonoBehaviour
{
public Tile highlightTile;
public TileBase[] highlightTiles;
public Tilemap highlightMap;
public int maxMoveTiles;
public bool highlight;
private Vector3Int previous, previousLeft, previousRight, previousForward, previousAft, previousVect;
private Vector3Int[] previousVectors;
void Start()
{
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
transform.localPosition = new Vector3(transform.localPosition.x,
transform.localPosition.y + 1,
transform.localPosition.z );
}
if (Input.GetKeyDown(KeyCode.S))
{
transform.localPosition = new Vector3(transform.localPosition.x,
transform.localPosition.y - 1,
transform.localPosition.z );
}
if (Input.GetKeyDown(KeyCode.D))
{
transform.localPosition = new Vector3(transform.localPosition.x + 1,
transform.localPosition.y,
transform.localPosition.z);
}
if (Input.GetKeyDown(KeyCode.A))
{
transform.localPosition = new Vector3(transform.localPosition.x - 1,
transform.localPosition.y,
transform.localPosition.z);
}
}
void LateUpdate()
{
if (highlight)
HighlightMoves();
else EraseHighlights();
}
private void HighlightMoves()
{
previousVectors = new Vector3Int[1];
highlightMap.SetTiles(previousVectors, null);
int tMax = 0;
Collider[] legalTiles = Physics.OverlapSphere(transform.position, maxMoveTiles/2);
previousVectors = new Vector3Int[legalTiles.Length];
foreach (Collider col in legalTiles)
{
//Vector3 conversionVector = new Vector3(col.transform.localPosition.x, col.transform.localPosition.y, col.transform.localPosition.z);
Vector3Int tileVector = Vector3Int.FloorToInt(col.transform.position);
previousVectors[tMax] = tileVector;
tMax++;
}
highlightMap.SetTiles(previousVectors, highlightTiles);
}
private void EraseHighlights()
{
//highlightMap.SetTile(previousForward, null);
//highlightMap.SetTile(previousAft, null);
//highlightMap.SetTile(previous, null);
//highlightMap.SetTile(previousRight, null);
//highlightMap.SetTile(previousLeft, null);
highlightMap.SetTiles(previousVectors, null);
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position, maxMoveTiles/2);
}
}
}
If you open a new 3D Project in Unity and setup a grid with a Tilemap, called highlightMap in my code example, you should be able to recreate this exactly, using the 2 scripts.
Everything is oriented in 2D, this means x+ is Right y+ is forward and z+ is up/dephth (unused by tilemaps).
The empty Collider prefab I have is an empty GO with pos 0,0,0. it has another empty GO Child, which has the Box Collider Component, and the transform value of this child is 0.5,0.5,0.5, so that the Collider is centered on top of each tile.
This is after 0 moves, so just pressed Play:
This is after 1 move forward, (y+1):
Instead of going by colliders at all afaik you could also just use GridLayout.WorldToCell like e.g.
Tilemap yourTileMap;
// see https://docs.unity3d.com/ScriptReference/Tilemaps.Tilemap-layoutGrid.html
var grid = yourTileMap.layoutGrid;
// The "Grid" implements "GridLayout"
// see https://docs.unity3d.com/ScriptReference/Grid.html
var currentCellPos = grid.WorldToCell(transform.position);
var currentCell = yourTileMap.GetTile(currentCellPos);
Then if you need to get multiple tiles I would probably go the "lazy/stupid" way and just do something like e.g.
var currentCellPos = grid.WorldToCell(transform.position);
var currentCell = yourTileMap.GetTile(currentCellPos);
var leftCellPos = grid.WorldToCell(transform.position - transform.right * someRange);
var leftCell = yourTileMap.GetTile(leftCellPos);
var rightCellPos = grid.WorldToCell(transform.position + transform.right * someRange);
var rightCell = yourTileMap.GetTile(rightCellPos);
var frontCellPos = grid.WorldToCell(transform.position + transform.forward * someRange);
var frontCell = yourTileMap.GetTile(frontCellPos);
var backCellPos = grid.WorldToCell(transform.position - transform.forward * someRange);
var backCell = yourTileMap.GetTile(backCellPos);
highlightTiles[tMax] = Instantiate(highlightTile, col.transform.parent.position, Quaternion.identity, transform);
I dont know why, but apparently I didnt instantiate the tiles themselves into an Array of tiles, so everytime I was ''placing'' them on the grid, it was actually placing an empty array.
Now its fixed! Just need to find a nice way to erase all after a move and im set!

Draw a Line on Canvas With Mouse Position Unity 3D

I followed a tutorial to draw a line using mouse position, the line will be drawn inside the canvas. But when running it, the line didn't drawn! and it gives me this error:
NullReferenceException: Object reference not set to an instance of an object
What's wrong in my code?
Here's the script:
public GameObject Line;
GameObject CurrentLine;
LineRenderer linerenderer;
private List<Vector2> FingerPositions;
public Canvas Can;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
CreateLine();
}
if (Input.GetMouseButton(0))
{
Vector2 tempfingerpos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (Vector2.Distance(tempfingerpos, FingerPositions[FingerPositions.Count - 1]) > 0.1f)
{
UpdateLine(tempfingerpos);
}
}
}
void CreateLine()
{
CurrentLine = Instantiate(Line, Vector3.zero, Quaternion.identity);
linerenderer = CurrentLine.GetComponent<LineRenderer>();
FingerPositions.Clear();
FingerPositions.Add(Camera.main.ScreenToWorldPoint(Input.mousePosition));
FingerPositions.Add(Camera.main.ScreenToWorldPoint(Input.mousePosition));
linerenderer.SetPosition(0, FingerPositions[0]);
linerenderer.SetPosition(0, FingerPositions[1]);
CurrentLine.transform.SetParent(Can.transform, false);
}
void UpdateLine(Vector2 NewFingerPos)
{
FingerPositions.Add(NewFingerPos);
linerenderer.positionCount ++;
linerenderer.SetPosition(linerenderer.positionCount - 1, NewFingerPos);
}
My suggestion is to try first to draw line renderer with fixed positions(You can add two empty objects and then draw line renderer between those objects).
And if that works, then move to the logic with fingers.
Keep in mind that you can't see line renderer if you are using screen space overlay, so you must use Canvas - World Space to see it over the canvas.
replace this
private List FingerPositions;
with this
private List<Vector2> FingerPositions = new List<Vector2>();

In Unity Arkit,how to show a text in UnityARHitTestExample scene until a vertical plane is found?

I am trying to show a text say "Scan for a surface" until it scans a plane surface.Once the device picks up a plane surface the message should disappear.Where should I write code for this purpose.I found two instances where prefab plane is initialised,one in UnityARGeneratePlane.cs and UnityARUtility.cs .I added a Gameobject as Text in UnityARGeneratePlane.cs and used setactive to true and false to show and hide the text.It is showing when i used it in the start method.How to hide the text is where i struggle.Where to use the code to hide the text when a plane is detected?Is it in UnityARGeneratePlane.cs or UnityARUtility.cs.
public class UnityARGeneratePlane : MonoBehaviour
{
public GameObject planePrefab;
public GameObject scantxt;
private UnityARAnchorManager unityARAnchorManager;
// Use this for initialization
void Start () {
unityARAnchorManager = new UnityARAnchorManager();
UnityARUtility.InitializePlanePrefab (planePrefab);
scantxt.SetActive(true); //Tried to show the text working when app opens
}
void OnDestroy()
{
unityARAnchorManager.Destroy ();
scantxt.SetActive(false); //Here is where I tried to hide the text until a Vertical or Horizontal plane is detected
}
void OnGUI()
{
IEnumerable<ARPlaneAnchorGameObject> arpags = unityARAnchorManager.GetCurrentPlaneAnchors ();
foreach(var planeAnchor in arpags)
{
//ARPlaneAnchor ap = planeAnchor;
//GUI.Box (new Rect (100, 100, 800, 60), string.Format ("Center: x:{0}, y:{1}, z:{2}", ap.center.x, ap.center.y, ap.center.z));
//GUI.Box(new Rect(100, 200, 800, 60), string.Format ("Extent: x:{0}, y:{1}, z:{2}", ap.extent.x, ap.extent.y, ap.extent.z));
}
}
}
The code below is UnityARUtility.cs
public class UnityARUtility
{
private MeshCollider meshCollider; //declared to avoid code stripping of class
private MeshFilter meshFilter; //declared to avoid code stripping of class
public static GameObject planePrefab = null;
// public Text text1;
public static void InitializePlanePrefab(GameObject go)
{
planePrefab = go;
}
public static GameObject CreatePlaneInScene(ARPlaneAnchor arPlaneAnchor)
{
GameObject plane;
if (planePrefab != null)
{
plane = GameObject.Instantiate(planePrefab); //I dont understand why again Plane prefab is initialized.Other than Generate planes.
// text1.text = "Select Any Painting from panel";
}
else {
plane = new GameObject (); //put in a blank gameObject to get at least a transform to manipulate
}
//plane.name = arPlaneAnchor.identifier;
ARKitPlaneMeshRender apmr = plane.GetComponent<ARKitPlaneMeshRender> ();
if (apmr != null) {
apmr.InitiliazeMesh (arPlaneAnchor);
}
return UpdatePlaneWithAnchorTransform(plane, arPlaneAnchor);
}
public static GameObject UpdatePlaneWithAnchorTransform(GameObject plane, ARPlaneAnchor arPlaneAnchor)
{
//do coordinate conversion from ARKit to Unity
plane.transform.position = UnityARMatrixOps.GetPosition (arPlaneAnchor.transform);
plane.transform.rotation = UnityARMatrixOps.GetRotation (arPlaneAnchor.transform);
ARKitPlaneMeshRender apmr = plane.GetComponent<ARKitPlaneMeshRender> ();
if (apmr != null) {
apmr.UpdateMesh (arPlaneAnchor);
}
MeshFilter mf = plane.GetComponentInChildren<MeshFilter> ();
if (mf != null) {
if (apmr == null) {
//since our plane mesh is actually 10mx10m in the world, we scale it here by 0.1f
mf.gameObject.transform.localScale = new Vector3 (arPlaneAnchor.extent.x * 0.1f, arPlaneAnchor.extent.y * 0.1f, arPlaneAnchor.extent.z * 0.1f);
//convert our center position to unity coords
mf.gameObject.transform.localPosition = new Vector3(arPlaneAnchor.center.x,arPlaneAnchor.center.y, -arPlaneAnchor.center.z);
}
}
return plane;
}
}
}

Draw mesh using material with different colors

I am making a grid based game. For it I need to debug certain tiles, for example where there is a collision and where the player is aiming. I have made a debugger class that draws a square mesh at a position using a color.
public class GridDebugger : MonoBehaviour {
[SerializeField] private float alpha;
private Mesh mesh;
private Material mat;
void Start() {
mat = new Material(Shader.Find("Sprites/Default"));
mesh = new Mesh();
mesh.vertices = new Vector3[] { new Vector3(.5f, .5f, 0), new Vector3(.5f, -.5f), new Vector3(-.5f, -.5f), new Vector3(-.5f, .5f) };
mesh.triangles = new int[] { 0, 1, 2, 2, 3, 0 };
}
public void Debug(Vector3 position, Color color) {
color.a = alpha;
mat.color = color;
Graphics.DrawMesh(mesh, position, Quaternion.identity, mat, 0);
}
}
Currently the class has two users:
[RequireComponent(typeof(GridDebugger))]
public class CollisionSystem : GridSystem {
private List<Node>[,] grid;
private GridDebugger debugger;
void Awake() {
debugger = GetComponent<GridDebugger>();
}
//Logic....
void Update() {
if (grid != null) {
for (int x = 0; x < grid.GetLength(0); x++) {
for (int y = 0; y < grid.GetLength(1); y++) {
if (grid[x, y] != null) {
for (int i = 0; i < grid[x, y].Count; i++) {
if (grid[x,y][i].Parent.Debug) {
Vector3 worldPos = GridToWorldPos(new Vector2Int(x, y), grid.GetLength(0), grid.GetLength(1));
worldPos.z = -0.0001f;
debugger.Debug(worldPos, Color.Red);
}
}
}
}
}
}
}
}
And
public class GridMeleeWeapon : MonoBehaviour {
private GridDebugger debugger;
void Awake() {
debugger = FindObjectOfType<GridDebugger>();
}
public void Aim(Vector2 dir) {
Vector3 position = transform.position + dir;
debugger.Debug(position, Color.blue);
}
}
In CollisionSystem I loop every collider and draw a red square at every position.
In GridMeleeWeapon I just draw a blue square where the player aims.
The issue is that every square is drawn with the color used in CollisionSystem i.e red. When drawing the blue squares in GridMeleeWeapon they turn out red. If I remove debugger.Debug(worldPos, Color.Red) in CollisionSystem the squares I draw from GridMeleeWeapon are displayed blue.
With the current code I can't seem to draw meshes of different colors. What I think is happening is that the color specified by the first caller are used for consecutive calls, even though the color of the material is changed but why I have no idea.
How do I set the color correctly?
Material in Unity 3D is a reference type.
Your code in GridMeleeWeapon and CollisionSystem use the same instance of GridDebugger and material. What happens is since you change the material color OnUpdate() it will change the color from blue to red instantly (every frame) on each object using this material.
Instead of passing a color to your debugger().Debug() method, pass a material with a different color. For instance create a material with color red and another material with color blue. Use these materials to set the color.

Tiled Object Layer Position drawing to the wrong spot

I know this question is very specific to those familiar with both tiled and monogame, so I'll try to be a thorough as possible. I've been working on this issue for 15+ hours and am desperate.
I'm trying to draw sprites to the screen using Tiled's object layer. I've created a new object layer, drew some rectangles to it, and added a custom property which I reference in my LoadContent method.
Here is my LoadContent Method:
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mymap = Content.Load<TiledMap>("Misc/newmap");
enemyShip = Content.Load<Texture2D>("Enemies/enemyship");
//TiledMapObject[] islands = mymap.GetLayer<TiledMapObjectLayer>("Islands").Objects;
ship_sprite = Content.Load<Texture2D>("character/wooden_ship");
Texture2D texture = Content.Load<Texture2D>("character/anima2");
animatedSprite = new AnimatedSprite(texture, 1, 2);
font = Content.Load<SpriteFont>("Misc/londrinasolid");
Song song = Content.Load<Song>("Music/Chad_Crouch_-_Stellars_Jay");
MediaPlayer.Volume = 0.7F;
MediaPlayer.Play(song);
TiledMapObject[] littleBoats = mymap.GetLayer<TiledMapObjectLayer>("SmallBoats").Objects;
foreach (var en in littleBoats)
{
string type;
en.Properties.TryGetValue("type", out type);
if (type == "smallboat")
{
Enemy.enemies.Add(new SmallBoat(en.Position));
}
}
// TODO: use this.Content to load your game content here
}
I've created a TiledMapObject Array which takes the items from the tiledmap object layer. It also checks the custom property name. If it it's "type", which you can see labeled in the bottom lefthand corner of the tiledmap picture, it takes that object and adds it to the array at the position on the tiledmap (at least it's supposed to).
In the draw method, I create a temporary Texture2D variable which references the aforementioned enemy list (which is now filled with two elements from the tiled map). If type Smallboat, it then draws the sprite I want to draw, which it does, just at the wrong position. Here is the relevant draw method:
foreach (Enemy en in Enemy.enemies)
{
Texture2D spritetoDraw;
int rad;
if (en.GetType() == typeof(SmallBoat))
{
rad = 16;
spritetoDraw = enemyShip;
}
else
{
rad = 30;
spritetoDraw = ship_sprite;
}
spriteBatch.Draw(spritetoDraw, new Vector2(en.Position.X - rad, en.Position.Y - rad), Color.White);
}
And here is the starting position of the enemy boat once I run, it's slightly offset from the origin 0,0 because in the draw method I subtract the radius:
Here is my Enemy class, with the SmallBoat child class at the bottom. I've created a new list which should contain the objects from the tiled layer once they are added in the LoadContent method in my main file. I've checked that the objects are being added by using Enemy.Remove(), and they are, so I know that at least the program recognizes the objects in the tiled file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace my_first_game
{
class Enemy
{
private Vector2 position;
protected int radius;
float circle = MathHelper.Pi * 2;
public float rotationAngle;
protected int health;
public static List<Enemy> enemies = new List<Enemy>();
public int Radius { get { return radius; } }
public Vector2 Position { get { return position; }}
public int Health { get { return health; } set { value = health; } }
public Enemy(Vector2 newpos)
{
newpos = position;
}
public void Update(GameTime gametime, Vector2 playerPos)
{
rotationAngle = circle % 2;
double dt = gametime.ElapsedGameTime.TotalSeconds;
Vector2 direction = new Vector2((float)Math.Cos(rotationAngle), (float)Math.Sin(rotationAngle));
Vector2 movedir = Position - playerPos;
movedir.Normalize();
position -= movedir;
}
}
class SmallBoat : Enemy
{
public SmallBoat(Vector2 newpos) : base(newpos)
{
//radius = 50;
}
}
}
What I've tried:
1). commented out all update methods and ran, nothing changes except the ship's don't move.
2). Drawn new rectangles, erased old ones, deleted and created object layers.
3). if I remove a rectangle from the object layer, there are less boats drawn to the screen once the game is running. Therefore I know that the enemies are being drawn to the screen, just not at the right position.
4). Changed the coordinates to a hardcoded fixed number in the draw method instead of en.position.X and en.position.Y. This changes the starting position to the desired location, but it's hardcoded and doesn't solve the problem.
5). Rearranged elements in the loadcontent method and draw method, to no avail.
It seems that the list is being properly referenced and that the issue is that for some reason the coordinates on the tiled map aren't transfering over. Much of my code is based off of a Udemy Monogame tutorial, and the loadcontent method and draw method are basically the same.
Any and all help is warmly welcomed. Please let me know if there's any other information I can provide.
Edit: Here is the entire draw method.
protected override void Draw(GameTime gameTime)
{
controller.controller_update(gameTime);
spriteBatch.Begin();
if (controller.ingame == false)
{
spriteBatch.DrawString(font, "Welcome to Thallasaphobia. \n press Enter to Begin", new Vector2(100, 100), Color.White);
}
spriteBatch.End();
if (controller.ingame == true)
{
GraphicsDevice.Clear(Color.Black);
mapRenderer.Draw(mymap, cam.GetViewMatrix());
spriteBatch.Begin(transformMatrix: cam.GetViewMatrix());
animatedSprite.Draw(spriteBatch, new Vector2(480, 350));
//create a new rectangle around the ship_sprite
Rectangle ship_rectangle = new Rectangle(0, 0, ship_sprite.Width, ship_sprite.Height);
Vector2 origin = new Vector2(ship_sprite.Width / 2, ship_sprite.Height + 15);
foreach (Enemy en in Enemy.enemies)
{
Texture2D spritetoDraw;
int rad;
if (en.GetType() == typeof(SmallBoat))
{
rad = 16;
spritetoDraw = enemyShip;
}
else
{
rad = 30;
spritetoDraw = ship_sprite;
}
spriteBatch.Draw(spritetoDraw, new Vector2(en.Position.X - rad, en.Position.Y - rad), Color.White);
}
spriteBatch.Draw(ship_sprite, ship.Position, ship_rectangle, Color.White, ship.rotationAngle + MathHelper.Pi/2, origin, 1.0f, SpriteEffects.None, 1);
}
spriteBatch.End();
base.Draw(gameTime);
}
Although I don't really have a means of testing this, I believe the problem is in your constructor. You currently have this code:
public Enemy(Vector2 newpos)
{
newpos = position;
}
You should actually have:
public Enemy(Vector2 newpos)
{
position = newpos;
}
Since "position" is the property of the Enemy class, THAT is the value we want updated, not newpos, which is just a parameter. So that would explain why your enemy is starting at the origin, because its position is never being initially set.

Categories