Unity C#中无法实例化Room类对象的问题排查
问题:Unity中创建Room对象时出现构造函数匹配错误
我有一个Unity C#脚本用于生成房间网格,房间由Room类定义并放在同名脚本中。当尝试为房间网格创建新的Room对象时,出现编译器错误:
'Room' 不包含接受3个参数的构造函数
同时还引发了更多连锁错误,提示Room不包含方法定义且找不到可访问的扩展方法。
Room类代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Drawing; public class Room { private Point coords; private string referenceName; private GameObject roomGO; private Room north, east, south, west; private int layer; public Room(string theReferenceName, Point theCoords, int theLayer) { referenceName = theReferenceName; coords = theCoords; layer = theLayer; } // 返回指定方向的相邻房间,无相邻则返回null public Room getNeighbor(string theNeighbor) { switch (theNeighbor) { case "north" : if (north is not null) { return north; } break; case "east" : if (east is not null) { return east; } break; case "south" : if (south is not null) { return south; } break; case "west" : if (west is not null) { return west; } break; } return null; } public void setNeighbor(string theDirection, Room theNewNeighbor) { switch (theDirection) { case "north" : north = theNewNeighbor; break; case "east" : east = theNewNeighbor; break; case "south" : south = theNewNeighbor; break; case "west" : west = theNewNeighbor; break; } } public void setRoomGO (GameObject theRoomGO) { if (theRoomGO != null) { roomGO = theRoomGO; } } public string getReferenceName() { return referenceName; } public void setReferenceName(string theNewReferenceName) { referenceName = theNewReferenceName; } public Point getCoords() { return coords; } public int getLayer() { return layer; } public void setLayer(int theNewLayer) { layer = theNewLayer; } }
创建Room对象的代码
for (int i = 0; i < Rows; i++) { for (int j = 0; j < Columns; j++) { dungeon[i, j] = new Room(" ", new Point(i, j), 0); } }
问题原因与解决方案
核心原因
你引入了System.Drawing命名空间,这个命名空间属于Windows桌面应用的GDI+库,Unity运行时环境不支持该库;同时该命名空间内的Point类与你代码中使用的坐标类型产生了命名冲突,导致编译器无法正确匹配Room的3参数构造函数,进而引发后续的方法定义找不到等连锁错误。
解决方案
方案1:改用Unity自带的整数坐标类型Vector2Int
- 移除
using System.Drawing;引用,修改Room类中与坐标相关的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Room { private Vector2Int coords; // 替换为Vector2Int private string referenceName; private GameObject roomGO; private Room north, east, south, west; private int layer; // 修改构造函数的参数类型 public Room(string theReferenceName, Vector2Int theCoords, int theLayer) { referenceName = theReferenceName; coords = theCoords; layer = theLayer; } // 修改getCoords的返回类型 public Vector2Int getCoords() { return coords; } // 其余方法代码保持不变 }
- 修改创建Room对象的代码:
for (int i = 0; i < Rows; i++) { for (int j = 0; j < Columns; j++) { dungeon[i, j] = new Room(" ", new Vector2Int(i, j), 0); } }
方案2:自定义Point类
如果需要保留Point的命名,可以自己实现一个简单的整数坐标类,避免与System.Drawing的Point冲突:
- 移除
using System.Drawing;引用,添加自定义Point类:
public class Point { public int X { get; set; } public int Y { get; set; } public Point(int x, int y) { X = x; Y = y; } }
- 保持Room类和创建对象的代码不变即可,此时编译器会使用你自定义的Point类。
额外检查
确保Room类的访问修饰符是public,且创建对象的脚本与Room类在同一个命名空间下,或者已通过using语句正确引用。
内容的提问来源于stack exchange,提问作者NVM99
相关产品推荐
相关产品推荐

