Merge branch 'feature/editor-gizmos' into develop
commit
d7e65dcaa5
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@ import {
|
||||||
CCFloat,
|
CCFloat,
|
||||||
CCInteger,
|
CCInteger,
|
||||||
Collider2D,
|
Collider2D,
|
||||||
|
Color,
|
||||||
Component,
|
Component,
|
||||||
Contact2DType,
|
Contact2DType,
|
||||||
geometry,
|
geometry,
|
||||||
|
@ -17,6 +18,7 @@ import {
|
||||||
import GameState from '../Enum/GameState';
|
import GameState from '../Enum/GameState';
|
||||||
import ScoreType from '../Enum/ScoreType';
|
import ScoreType from '../Enum/ScoreType';
|
||||||
import GameEvent from '../Events/GameEvent';
|
import GameEvent from '../Events/GameEvent';
|
||||||
|
import Gizmos2D from '../Gizmos/Gizmos2D';
|
||||||
import AudioManager from '../Manager/AudioManager';
|
import AudioManager from '../Manager/AudioManager';
|
||||||
import { EventManger } from '../Manager/EventManger';
|
import { EventManger } from '../Manager/EventManger';
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
@ -53,6 +55,16 @@ export class Enemy extends Component {
|
||||||
private _isActive = false;
|
private _isActive = false;
|
||||||
private _currentGoal = 0;
|
private _currentGoal = 0;
|
||||||
|
|
||||||
|
onFocusInEditor(): void {
|
||||||
|
Gizmos2D.registerDrawGizmos(this.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrawGizmosSelected(): void {
|
||||||
|
Gizmos2D.beginColor(this.node, Color.RED);
|
||||||
|
Gizmos2D.drawSolidCircle(this.node, this._patrolPoint1.worldPosition, 20);
|
||||||
|
Gizmos2D.drawSolidCircle(this.node, this._patrolPoint2.worldPosition, 20);
|
||||||
|
}
|
||||||
|
|
||||||
protected onLoad(): void {
|
protected onLoad(): void {
|
||||||
EventManger.instance.on(GameEvent.Score, this.onScore, this);
|
EventManger.instance.on(GameEvent.Score, this.onScore, this);
|
||||||
EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this);
|
EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this);
|
||||||
|
|
|
@ -1,6 +1,19 @@
|
||||||
import { _decorator, AudioClip, Collider2D, Component, Contact2DType, Node, ParticleSystem, Prefab, Vec2 } from 'cc';
|
import {
|
||||||
|
_decorator,
|
||||||
|
AudioClip,
|
||||||
|
Collider2D,
|
||||||
|
Color,
|
||||||
|
Component,
|
||||||
|
Contact2DType,
|
||||||
|
Node,
|
||||||
|
ParticleSystem,
|
||||||
|
PolygonCollider2D,
|
||||||
|
Prefab,
|
||||||
|
Vec2,
|
||||||
|
} from 'cc';
|
||||||
import TimeConfig from '../Enum/TimeConfig';
|
import TimeConfig from '../Enum/TimeConfig';
|
||||||
import { CameraController } from '../Environments/CameraController';
|
import { CameraController } from '../Environments/CameraController';
|
||||||
|
import Gizmos2D from '../Gizmos/Gizmos2D';
|
||||||
import AudioManager from '../Manager/AudioManager';
|
import AudioManager from '../Manager/AudioManager';
|
||||||
import { GameManager } from '../Manager/GameManager';
|
import { GameManager } from '../Manager/GameManager';
|
||||||
import ObjectPool from '../Pool/ObjectPool';
|
import ObjectPool from '../Pool/ObjectPool';
|
||||||
|
@ -28,6 +41,21 @@ export class MultiBall extends Component {
|
||||||
|
|
||||||
private _enabled: boolean = true;
|
private _enabled: boolean = true;
|
||||||
|
|
||||||
|
onFocusInEditor(): void {
|
||||||
|
Gizmos2D.registerDrawGizmos(this.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrawGizmos(): void {
|
||||||
|
Gizmos2D.beginColor(this.node, new Color(0, 255, 0, 200));
|
||||||
|
const points = (this._collider as PolygonCollider2D).points.map((p) => p.clone().add(this._collider.offset));
|
||||||
|
Gizmos2D.beginLocalPosition(this.node);
|
||||||
|
Gizmos2D.drawSolidPolygon(this.node, points);
|
||||||
|
Gizmos2D.endLocalPosition(this.node);
|
||||||
|
Gizmos2D.beginColor(this.node, new Color(0, 0, 255, 200));
|
||||||
|
Gizmos2D.drawSolidEllipse(this.node, this._portLeft.worldPosition, 20, 30);
|
||||||
|
Gizmos2D.drawSolidEllipse(this.node, this._portRight.worldPosition, 20, 30);
|
||||||
|
}
|
||||||
|
|
||||||
protected onLoad(): void {
|
protected onLoad(): void {
|
||||||
this._fxPool = new ObjectPool(this._fx, 2, true);
|
this._fxPool = new ObjectPool(this._fx, 2, true);
|
||||||
this._collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
this._collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"ver": "1.2.0",
|
||||||
|
"importer": "directory",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "4e8d436e-a896-448d-8a6c-cd598f2fd34a",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
import { EDITOR, EDITOR_NOT_IN_PREVIEW } from 'cc/env';
|
||||||
|
|
||||||
|
export const cce = EDITOR_NOT_IN_PREVIEW && (window as any).cce;
|
||||||
|
export const Editor = EDITOR && (window as any).Editor;
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "6380d835-23a8-4a24-9114-22ef1765f260",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
declare module 'cc' {
|
||||||
|
interface Component {
|
||||||
|
/**
|
||||||
|
* Call per frame in editor (Only use in editor)
|
||||||
|
*/
|
||||||
|
onDrawGizmos(): void;
|
||||||
|
/**
|
||||||
|
* Call per frame in editor when node selected (Only use in editor)
|
||||||
|
*/
|
||||||
|
onDrawGizmosSelected(): void;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "f1fafa13-305c-4113-8348-33754b0582a8",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
|
@ -0,0 +1,435 @@
|
||||||
|
import { _decorator, CCObject, Color, Component, Graphics, IVec2Like, Layers, Node, toRadian, Vec3 } from 'cc';
|
||||||
|
import { Editor } from './Define';
|
||||||
|
|
||||||
|
const { ccclass, executeInEditMode } = _decorator;
|
||||||
|
|
||||||
|
class GizmosRenderer {
|
||||||
|
private _graphic: Graphics;
|
||||||
|
private _drawCalls: ((graphic: Graphics) => void)[] = [];
|
||||||
|
|
||||||
|
public addDrawCall(drawCall: (graphic: Graphics) => void) {
|
||||||
|
this._drawCalls.push(drawCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(graphic: Graphics) {
|
||||||
|
this._graphic = graphic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear() {
|
||||||
|
this._graphic.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setLayer(layer: Layers.Enum) {
|
||||||
|
this._graphic.node.layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public draw() {
|
||||||
|
this._drawCalls.forEach((drawCall) => {
|
||||||
|
drawCall(this._graphic);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._drawCalls = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ccclass('Gizmos2D.GizmosDebugDraw')
|
||||||
|
@executeInEditMode
|
||||||
|
class GizmosDebugDraw extends Component {
|
||||||
|
private _renderers: Map<string, GizmosRenderer> = new Map();
|
||||||
|
private _color: Color = Gizmos2D.DEFAULT_COLOR;
|
||||||
|
private _useLocalPosition: boolean = false;
|
||||||
|
private _layer: Layers.Enum = Gizmos2D.DEFAULT_LAYER;
|
||||||
|
private _parentNode: Node;
|
||||||
|
|
||||||
|
protected update(dt: number): void {
|
||||||
|
//only call in editor
|
||||||
|
this.callNodeDrawGizmos();
|
||||||
|
|
||||||
|
this._renderers.forEach((renderer) => {
|
||||||
|
renderer.clear();
|
||||||
|
renderer.draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._color = Gizmos2D.DEFAULT_COLOR;
|
||||||
|
this._useLocalPosition = false;
|
||||||
|
this._layer = Gizmos2D.DEFAULT_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private callNodeDrawGizmos() {
|
||||||
|
if (Editor && this._parentNode) {
|
||||||
|
const selectedList: string[] = Editor.Selection.getSelected('node');
|
||||||
|
if (selectedList.includes(this._parentNode.uuid)) {
|
||||||
|
const comps = this._parentNode.components;
|
||||||
|
for (let i = 0; i < comps.length; i++) {
|
||||||
|
const comp: Component = comps[i];
|
||||||
|
comp.onDrawGizmosSelected?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const comps = this._parentNode.components;
|
||||||
|
for (let i = 0; i < comps.length; i++) {
|
||||||
|
const comp: Component = comps[i];
|
||||||
|
comp.onDrawGizmos?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createRenderer(color: Color) {
|
||||||
|
const hex = color.toHEX();
|
||||||
|
const g = new Node(`color ${hex}`).addComponent(Graphics);
|
||||||
|
g.lineWidth = 5;
|
||||||
|
g.strokeColor = color;
|
||||||
|
g.fillColor = color;
|
||||||
|
g.node.layer = this.node.layer;
|
||||||
|
g.node.parent = this.node;
|
||||||
|
const renderer = new GizmosRenderer(g);
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getRenderer(color: Color): GizmosRenderer {
|
||||||
|
const hex = color.toHEX();
|
||||||
|
let renderer = this._renderers.get(hex);
|
||||||
|
if (!renderer) {
|
||||||
|
renderer = this.createRenderer(color);
|
||||||
|
this._renderers.set(hex, renderer);
|
||||||
|
}
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private worldToLocal(world: IVec2Like): IVec2Like {
|
||||||
|
const local = new Vec3();
|
||||||
|
this.node.inverseTransformPoint(local, new Vec3(world.x, world.y));
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
|
||||||
|
public registerDrawGizmos(node: Node) {
|
||||||
|
this._parentNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setColor(color: Color) {
|
||||||
|
this._color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setUseLocalPosition(value: boolean) {
|
||||||
|
this._useLocalPosition = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setLayer(layer: Layers.Enum) {
|
||||||
|
this._layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearAll() {
|
||||||
|
this._renderers.forEach((renderer) => renderer.clear());
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawLine(point1: IVec2Like, point2: IVec2Like) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const p1 = this._useLocalPosition ? point1 : this.worldToLocal(point1);
|
||||||
|
const p2 = this._useLocalPosition ? point1 : this.worldToLocal(point2);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.moveTo(p1.x, p1.y);
|
||||||
|
g.lineTo(p2.x, p2.y);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawLineList(points: IVec2Like[], close: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const pointList = this._useLocalPosition ? points : points.map((p) => this.worldToLocal(p));
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
if (points.length > 0) {
|
||||||
|
const p0 = pointList[0];
|
||||||
|
g.moveTo(p0.x, p0.y);
|
||||||
|
for (let i = 1; i < pointList.length; i++) {
|
||||||
|
const p = pointList[i];
|
||||||
|
g.lineTo(p.x, p.y);
|
||||||
|
}
|
||||||
|
if (close) g.close();
|
||||||
|
g.stroke();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawCircle(center: IVec2Like, radius: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const c = this._useLocalPosition ? center : this.worldToLocal(center);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.circle(c.x, c.y, radius);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSolidCircle(center: IVec2Like, radius: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const c = this._useLocalPosition ? center : this.worldToLocal(center);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.circle(c.x, c.y, radius);
|
||||||
|
g.fill();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawRect(position: IVec2Like, width: number, height: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const p = this._useLocalPosition ? position : this.worldToLocal(position);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.rect(p.x, p.y, width, height);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSolidRect(position: IVec2Like, width: number, height: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const p = this._useLocalPosition ? position : this.worldToLocal(position);
|
||||||
|
const topLeft = {
|
||||||
|
x: p.x - width / 2,
|
||||||
|
y: p.y - height / 2,
|
||||||
|
};
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.rect(topLeft.x, topLeft.y, width, height);
|
||||||
|
g.fill();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSolidPolygon(points: IVec2Like[]) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const pointList = this._useLocalPosition ? points : points.map((p) => this.worldToLocal(p));
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
if (points.length > 0) {
|
||||||
|
const p0 = pointList[0];
|
||||||
|
g.moveTo(p0.x, p0.y);
|
||||||
|
for (let i = 1; i < pointList.length; i++) {
|
||||||
|
const p = pointList[i];
|
||||||
|
g.lineTo(p.x, p.y);
|
||||||
|
}
|
||||||
|
g.close();
|
||||||
|
g.fill();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawEllipse(center: IVec2Like, radiusX: number, radiusY: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const c = this._useLocalPosition ? center : this.worldToLocal(center);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.ellipse(c.x, c.y, radiusX, radiusY);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSolidEllipse(center: IVec2Like, radiusX: number, radiusY: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const c = this._useLocalPosition ? center : this.worldToLocal(center);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.ellipse(c.x, c.y, radiusX, radiusY);
|
||||||
|
g.fill();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawArc(
|
||||||
|
center: IVec2Like,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
counterclockwise: boolean = false,
|
||||||
|
) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const c = this._useLocalPosition ? center : this.worldToLocal(center);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.arc(c.x, c.y, radius, toRadian(startAngle), toRadian(endAngle), counterclockwise);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSolidArc(
|
||||||
|
center: IVec2Like,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
counterclockwise: boolean = false,
|
||||||
|
) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const c = this._useLocalPosition ? center : this.worldToLocal(center);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.arc(c.x, c.y, radius, toRadian(startAngle), toRadian(endAngle), counterclockwise);
|
||||||
|
g.lineTo(c.x, c.y);
|
||||||
|
g.fill();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawBezierCurves(point1: IVec2Like, point2: IVec2Like, point3: IVec2Like, point4: IVec2Like) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const p1 = this._useLocalPosition ? point1 : this.worldToLocal(point1);
|
||||||
|
const p2 = this._useLocalPosition ? point2 : this.worldToLocal(point2);
|
||||||
|
const p3 = this._useLocalPosition ? point3 : this.worldToLocal(point3);
|
||||||
|
const p4 = this._useLocalPosition ? point4 : this.worldToLocal(point4);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.moveTo(p1.x, p1.y);
|
||||||
|
g.bezierCurveTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawQuadraticCurve(point1: IVec2Like, point2: IVec2Like, point3: IVec2Like) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
renderer.setLayer(this._layer);
|
||||||
|
const p1 = this._useLocalPosition ? point1 : this.worldToLocal(point1);
|
||||||
|
const p2 = this._useLocalPosition ? point2 : this.worldToLocal(point2);
|
||||||
|
const p3 = this._useLocalPosition ? point3 : this.worldToLocal(point3);
|
||||||
|
renderer.addDrawCall((g) => {
|
||||||
|
g.moveTo(p1.x, p1.y);
|
||||||
|
g.quadraticCurveTo(p2.x, p2.y, p3.x, p3.y);
|
||||||
|
g.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Gizmos2D {
|
||||||
|
public static readonly DEFAULT_COLOR = Color.BLUE;
|
||||||
|
public static readonly DEFAULT_LAYER = Layers.Enum.GIZMOS;
|
||||||
|
|
||||||
|
private static getDebugNode(node: Node) {
|
||||||
|
let debugNode = node.getComponentInChildren(GizmosDebugDraw);
|
||||||
|
if (!debugNode) {
|
||||||
|
debugNode = new Node('DEBUG_DRAW_NODE').addComponent(GizmosDebugDraw);
|
||||||
|
debugNode.node.layer = this.DEFAULT_LAYER;
|
||||||
|
debugNode.node.hideFlags |= CCObject.Flags.DontSave | CCObject.Flags.HideInHierarchy;
|
||||||
|
debugNode.node.parent = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return debugNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static registerDrawGizmos(node: Node) {
|
||||||
|
this.getDebugNode(node).registerDrawGizmos(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static beginColor(node: Node, color: Color) {
|
||||||
|
this.getDebugNode(node).setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static beginLocalPosition(node: Node) {
|
||||||
|
this.getDebugNode(node).setUseLocalPosition(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static endLocalPosition(node: Node) {
|
||||||
|
this.getDebugNode(node).setUseLocalPosition(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static beginLayer(node: Node, layer: Layers.Enum) {
|
||||||
|
this.getDebugNode(node).setLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static clearAll(node: Node) {
|
||||||
|
this.getDebugNode(node).clearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawLine(node: Node, point1: IVec2Like, point2: IVec2Like) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawLine(point1, point2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawLineList(node: Node, points: IVec2Like[], close: boolean = false) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawLineList(points, close);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawCircle(node: Node, center: IVec2Like, radius: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawCircle(center, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSolidCircle(node: Node, center: IVec2Like, radius: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSolidCircle(center, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawRect(node: Node, position: IVec2Like, width: number, height: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawRect(position, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSolidRect(node: Node, position: IVec2Like, width: number, height: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSolidRect(position, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSolidPolygon(node: Node, positions: IVec2Like[]) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSolidPolygon(positions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawEllipse(node: Node, center: IVec2Like, radiusX: number, radiusY: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawEllipse(center, radiusX, radiusY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSolidEllipse(node: Node, center: IVec2Like, radiusX: number, radiusY: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSolidEllipse(center, radiusX, radiusY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawArc(
|
||||||
|
node: Node,
|
||||||
|
center: IVec2Like,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
counterclockwise: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawArc(center, radius, startAngle, endAngle, counterclockwise);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSolidArc(
|
||||||
|
node: Node,
|
||||||
|
center: IVec2Like,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
counterclockwise: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSolidArc(center, radius, startAngle, endAngle, counterclockwise);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawBezierCurves(
|
||||||
|
node: Node,
|
||||||
|
point1: IVec2Like,
|
||||||
|
point2: IVec2Like,
|
||||||
|
point3: IVec2Like,
|
||||||
|
point4: IVec2Like,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawBezierCurves(point1, point2, point3, point4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawQuadraticCurve(node: Node, point1: IVec2Like, point2: IVec2Like, point3: IVec2Like) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawQuadraticCurve(point1, point2, point3);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "a7db21b7-2ab4-4180-b95b-86a2019340e5",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
|
@ -0,0 +1,619 @@
|
||||||
|
import {
|
||||||
|
_decorator,
|
||||||
|
Camera,
|
||||||
|
CCObject,
|
||||||
|
Color,
|
||||||
|
Component,
|
||||||
|
director,
|
||||||
|
geometry,
|
||||||
|
GeometryRenderer,
|
||||||
|
gfx,
|
||||||
|
Layers,
|
||||||
|
Mat4,
|
||||||
|
Material,
|
||||||
|
Node,
|
||||||
|
toRadian,
|
||||||
|
Vec3,
|
||||||
|
} from 'cc';
|
||||||
|
import { cce, Editor } from './Define';
|
||||||
|
|
||||||
|
const { ccclass, executeInEditMode, property } = _decorator;
|
||||||
|
|
||||||
|
class GizmosRenderer {
|
||||||
|
private _geometryRenderer;
|
||||||
|
private _drawCalls: ((geometry) => void)[] = [];
|
||||||
|
|
||||||
|
constructor(geometryRenderer: GeometryRenderer) {
|
||||||
|
this._geometryRenderer = geometryRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addDrawCall(drawCall: (geometry: GeometryRenderer) => void) {
|
||||||
|
this._drawCalls.push(drawCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear() {
|
||||||
|
this._drawCalls = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public draw() {
|
||||||
|
this._drawCalls.forEach((drawCall) => {
|
||||||
|
drawCall(this._geometryRenderer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ccclass('Gizmos3D.GizmosDebugDraw')
|
||||||
|
@executeInEditMode
|
||||||
|
class GizmosDebugDraw extends Component {
|
||||||
|
private _renderers: Map<string, GizmosRenderer> = new Map();
|
||||||
|
private _color: Color = Gizmos3D.DEFAULT_COLOR;
|
||||||
|
private _renderer: GeometryRenderer = null;
|
||||||
|
private _depthTest: boolean = false;
|
||||||
|
private _useLocalPosition: boolean = false;
|
||||||
|
private _parentNode: Node;
|
||||||
|
|
||||||
|
protected onLoad(): void {
|
||||||
|
if (cce) {
|
||||||
|
cce.Camera._camera.camera.initGeometryRenderer();
|
||||||
|
this._renderer = cce.Camera._camera.camera.geometryRenderer;
|
||||||
|
} else {
|
||||||
|
const camera = director.getScene().getComponentInChildren(Camera).camera;
|
||||||
|
camera.initGeometryRenderer();
|
||||||
|
this._renderer = camera.geometryRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._renderer) {
|
||||||
|
console.warn(
|
||||||
|
'Unable to initialize geometryRenderer for Gizmos3D, please ensure the Geometry Renderer feature is enabled in project settings if you want to use Gizmos3D in play mode',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected update(dt: number): void {
|
||||||
|
//only call in editor
|
||||||
|
this.callNodeDrawGizmos();
|
||||||
|
|
||||||
|
this._renderers.forEach((renderer) => {
|
||||||
|
renderer.draw();
|
||||||
|
renderer.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._color = Gizmos3D.DEFAULT_COLOR;
|
||||||
|
this._useLocalPosition = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private callNodeDrawGizmos() {
|
||||||
|
if (Editor && this._parentNode) {
|
||||||
|
const selectedList: string[] = Editor.Selection.getSelected('node');
|
||||||
|
if (selectedList.includes(this._parentNode.uuid)) {
|
||||||
|
const comps = this._parentNode.components;
|
||||||
|
for (let i = 0; i < comps.length; i++) {
|
||||||
|
const comp: Component = comps[i];
|
||||||
|
comp.onDrawGizmos?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createRenderer(color: Color) {
|
||||||
|
const renderer = new GizmosRenderer(this._renderer);
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getRenderer(color: Color): GizmosRenderer {
|
||||||
|
const hex = color.toHEX();
|
||||||
|
let renderer = this._renderers.get(hex);
|
||||||
|
if (!renderer) {
|
||||||
|
renderer = this.createRenderer(color);
|
||||||
|
this._renderers.set(hex, renderer);
|
||||||
|
}
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private worldToLocal(world: Vec3): Vec3 {
|
||||||
|
const local = new Vec3();
|
||||||
|
Vec3.add(local, this.node.worldPosition, world);
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
|
||||||
|
public registerDrawGizmos(node: Node) {
|
||||||
|
this._parentNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDepthTest(value: boolean) {
|
||||||
|
this._depthTest = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setColor(color: Color) {
|
||||||
|
this._color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setUseLocalPosition(value: boolean) {
|
||||||
|
this._useLocalPosition = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearAll() {
|
||||||
|
this._renderers.forEach((renderer) => renderer.clear());
|
||||||
|
}
|
||||||
|
|
||||||
|
private rotate(pos: Vec3, rot: Vec3 = Vec3.ZERO): Mat4 {
|
||||||
|
let result = new Mat4();
|
||||||
|
let transform = new Mat4();
|
||||||
|
|
||||||
|
Mat4.fromTranslation(result, pos);
|
||||||
|
|
||||||
|
Mat4.fromXRotation(transform, toRadian(rot.x));
|
||||||
|
result.multiply(transform);
|
||||||
|
|
||||||
|
Mat4.fromYRotation(transform, toRadian(rot.y));
|
||||||
|
result.multiply(transform);
|
||||||
|
|
||||||
|
Mat4.fromZRotation(transform, toRadian(rot.z));
|
||||||
|
result.multiply(transform);
|
||||||
|
|
||||||
|
Mat4.fromTranslation(transform, new Vec3(-pos.x, -pos.y, -pos.z));
|
||||||
|
result.multiply(transform);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawLine(point1: Vec3, point2: Vec3) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p1 = this._useLocalPosition ? this.worldToLocal(point1) : point1;
|
||||||
|
const p2 = this._useLocalPosition ? this.worldToLocal(point2) : point2;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addLine(p1, p2, color, this._depthTest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawLineList(points: Vec3[], close: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const pointList = this._useLocalPosition ? points.map((p) => this.worldToLocal(p)) : points;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
if (pointList.length > 0) {
|
||||||
|
for (let i = 0; i < pointList.length - 1; i++) {
|
||||||
|
geometry?.addLine(pointList[i], pointList[i + 1], color, this._depthTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close) {
|
||||||
|
geometry?.addLine(pointList[pointList.length - 1], pointList[0], color, this._depthTest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawDashLine(point1: Vec3, point2: Vec3) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p1 = this._useLocalPosition ? this.worldToLocal(point1) : point1;
|
||||||
|
const p2 = this._useLocalPosition ? this.worldToLocal(point2) : point2;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addDashedLine(p1, p2, color, this._depthTest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawDashLineList(points: Vec3[], close: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const pointList = this._useLocalPosition ? points.map((p) => this.worldToLocal(p)) : points;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
if (pointList.length > 0) {
|
||||||
|
for (let i = 0; i < pointList.length - 1; i++) {
|
||||||
|
geometry?.addDashedLine(pointList[i], pointList[i + 1], color, this._depthTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close) {
|
||||||
|
geometry?.addDashedLine(pointList[pointList.length - 1], pointList[0], color, this._depthTest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawCircle(center: Vec3, radius: number, rot: Vec3 = Vec3.ZERO) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const c = this._useLocalPosition ? this.worldToLocal(center) : center;
|
||||||
|
const transform = this.rotate(c, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addCircle(c, radius, color, 32, this._depthTest, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawDisc(center: Vec3, radius: number, rot: Vec3 = Vec3.ZERO, wireFrame: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const c = this._useLocalPosition ? this.worldToLocal(center) : center;
|
||||||
|
const transform = this.rotate(c, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addDisc(c, radius, color, 32, wireFrame, this._depthTest, true, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawQuad(point1: Vec3, point2: Vec3, point3: Vec3, point4: Vec3, wireFrame: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p1 = this._useLocalPosition ? this.worldToLocal(point1) : point1;
|
||||||
|
const p2 = this._useLocalPosition ? this.worldToLocal(point2) : point2;
|
||||||
|
const p3 = this._useLocalPosition ? this.worldToLocal(point3) : point3;
|
||||||
|
const p4 = this._useLocalPosition ? this.worldToLocal(point4) : point4;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addQuad(p1, p2, p3, p4, color, wireFrame, this._depthTest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSphere(center: Vec3, radius: number, wireFrame: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const c = this._useLocalPosition ? this.worldToLocal(center) : center;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addSphere(c, radius, color, 32, 16, wireFrame, this._depthTest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawArc(center: Vec3, radius: number, startAngle: number, endAngle: number, rot: Vec3 = Vec3.ZERO) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const c = this._useLocalPosition ? this.worldToLocal(center) : center;
|
||||||
|
const transform = this.rotate(c, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addArc(c, radius, color, startAngle, endAngle, 32, this._depthTest, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSolidArc(
|
||||||
|
center: Vec3,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const c = this._useLocalPosition ? this.worldToLocal(center) : center;
|
||||||
|
const transform = this.rotate(c, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addSector(
|
||||||
|
c,
|
||||||
|
radius,
|
||||||
|
color,
|
||||||
|
startAngle,
|
||||||
|
endAngle,
|
||||||
|
32,
|
||||||
|
wireFrame,
|
||||||
|
this._depthTest,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
transform,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawPolygon(
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
segments: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
const transform = this.rotate(p, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addPolygon(p, radius, color, segments, wireFrame, this._depthTest, true, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawOctahedron(position: Vec3, radius: number, rot: Vec3 = Vec3.ZERO, wireFrame: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
const transform = this.rotate(p, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addOctahedron(p, radius, color, wireFrame, this._depthTest, false, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawCross(position: Vec3, size: number) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addCross(p, size, color, this._depthTest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawCapsule(
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
height: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
const transform = this.rotate(p, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addCapsule(p, radius, height, color, 32, 8, wireFrame, this._depthTest, false, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawBox(position: Vec3, size: Vec3, rot: Vec3 = Vec3.ZERO, wireFrame: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
const transform = this.rotate(p, rot);
|
||||||
|
let box = geometry?.AABB.create(p.x, p.y, p.z, size.x, size.y, size.z);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addBoundingBox(box, color, wireFrame, this._depthTest, false, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawCylinder(
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
height: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
const transform = this.rotate(p, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addCylinder(p, radius, height, color, 32, wireFrame, this._depthTest, false, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawCone(position: Vec3, radius: number, height: number, rot: Vec3 = Vec3.ZERO, wireFrame: boolean = false) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p = this._useLocalPosition ? this.worldToLocal(position) : position;
|
||||||
|
const transform = this.rotate(p, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addCone(p, radius, height, color, 32, wireFrame, this._depthTest, false, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawBezier(point1: Vec3, point2: Vec3, point3: Vec3, point4: Vec3, rot: Vec3 = Vec3.ZERO) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const p1 = this._useLocalPosition ? this.worldToLocal(point1) : point1;
|
||||||
|
const p2 = this._useLocalPosition ? this.worldToLocal(point2) : point2;
|
||||||
|
const p3 = this._useLocalPosition ? this.worldToLocal(point3) : point3;
|
||||||
|
const p4 = this._useLocalPosition ? this.worldToLocal(point4) : point4;
|
||||||
|
const transform = this.rotate(p1, rot);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addBezier(p1, p2, p3, p4, color, 32, this._depthTest, true, transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawSpline(knots: Vec3[], mode: geometry.SplineMode = geometry?.SplineMode.BEZIER, knotSize = 0.5) {
|
||||||
|
const color = this._color.clone();
|
||||||
|
const renderer = this.getRenderer(color);
|
||||||
|
const knotsList = this._useLocalPosition ? knots.map((knot) => this.worldToLocal(knot)) : knots;
|
||||||
|
let spline = geometry?.Spline.create(mode, knotsList);
|
||||||
|
renderer.addDrawCall((geometry) => {
|
||||||
|
geometry?.addSpline(spline, color, 0xffffffff, knotSize, 32, this._depthTest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Gizmos3D {
|
||||||
|
private static _mat: Material;
|
||||||
|
|
||||||
|
public static get DEFAULT_MAT() {
|
||||||
|
if (!this._mat) {
|
||||||
|
this._mat = new Material();
|
||||||
|
this._mat.initialize({
|
||||||
|
effectName: 'builtin-unlit',
|
||||||
|
defines: { USE_VERTEX_COLOR: true },
|
||||||
|
states: { primitive: gfx.PrimitiveMode.LINE_LOOP },
|
||||||
|
});
|
||||||
|
this._mat.passes.forEach((v) => v.tryCompile());
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DEFAULT_COLOR = Color.BLUE;
|
||||||
|
public static readonly DEFAULT_LAYER = Layers.Enum.GIZMOS;
|
||||||
|
|
||||||
|
private static getDebugNode(node: Node) {
|
||||||
|
let debugNode = node.getComponentInChildren(GizmosDebugDraw);
|
||||||
|
if (!debugNode) {
|
||||||
|
debugNode = new Node('DEBUG_DRAW_NODE').addComponent(GizmosDebugDraw);
|
||||||
|
debugNode.node.layer = this.DEFAULT_LAYER;
|
||||||
|
debugNode.node.hideFlags |= CCObject.Flags.DontSave | CCObject.Flags.HideInHierarchy;
|
||||||
|
debugNode.node.parent = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return debugNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static registerDrawGizmos(node: Node) {
|
||||||
|
this.getDebugNode(node).registerDrawGizmos(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static beginColor(node: Node, color: Color) {
|
||||||
|
this.getDebugNode(node).setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static beginLocalPosition(node: Node) {
|
||||||
|
this.getDebugNode(node).setUseLocalPosition(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endLocalPosition(node: Node) {
|
||||||
|
this.getDebugNode(node).setUseLocalPosition(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static clearAll(node: Node) {
|
||||||
|
this.getDebugNode(node).clearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawLine(node: Node, point1: Vec3, point2: Vec3) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawLine(point1, point2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawLineList(node: Node, points: Vec3[], close: boolean = false) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawLineList(points, close);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawDashLine(node: Node, point1: Vec3, point2: Vec3) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawDashLine(point1, point2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawDashLineList(node: Node, points: Vec3[], close: boolean = false) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawLineList(points, close);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawCircle(node: Node, center: Vec3, radius: number, rot: Vec3 = Vec3.ZERO) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawCircle(center, radius, rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawDisc(
|
||||||
|
node: Node,
|
||||||
|
center: Vec3,
|
||||||
|
radius: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawDisc(center, radius, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawQuad(
|
||||||
|
node: Node,
|
||||||
|
point1: Vec3,
|
||||||
|
point2: Vec3,
|
||||||
|
point3: Vec3,
|
||||||
|
point4: Vec3,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawQuad(point1, point2, point3, point4, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSphere(node: Node, center: Vec3, radius: number, wireFrame: boolean = false) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSphere(center, radius, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawArc(
|
||||||
|
node: Node,
|
||||||
|
center: Vec3,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawArc(center, radius, startAngle, endAngle, rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSolidArc(
|
||||||
|
node: Node,
|
||||||
|
center: Vec3,
|
||||||
|
radius: number,
|
||||||
|
startAngle: number,
|
||||||
|
endAngle: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSolidArc(center, radius, startAngle, endAngle, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawPolygon(
|
||||||
|
node: Node,
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
segments: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawPolygon(position, radius, segments, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawOctahedron(
|
||||||
|
node: Node,
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawOctahedron(position, radius, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawCross(node: Node, center: Vec3, size: number) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawCross(center, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawCapsule(
|
||||||
|
node: Node,
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
height: number,
|
||||||
|
rot?: Vec3,
|
||||||
|
wireFrame?: boolean,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawCapsule(position, radius, height, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawBox(node: Node, center: Vec3, size: Vec3, rot?: Vec3, wireFrame?: boolean) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawBox(center, size, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawCylinder(
|
||||||
|
node: Node,
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
height: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawCylinder(position, radius, height, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawCone(
|
||||||
|
node: Node,
|
||||||
|
position: Vec3,
|
||||||
|
radius: number,
|
||||||
|
height: number,
|
||||||
|
rot: Vec3 = Vec3.ZERO,
|
||||||
|
wireFrame: boolean = false,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawCone(position, radius, height, rot, wireFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawBezier(node: Node, point1: Vec3, point2: Vec3, point3: Vec3, point4: Vec3, rot?: Vec3) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawBezier(point1, point2, point3, point4, rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static drawSpline(
|
||||||
|
node: Node,
|
||||||
|
knots: Vec3[],
|
||||||
|
mode: geometry.SplineMode = geometry?.SplineMode.BEZIER,
|
||||||
|
knotSize = 0.5,
|
||||||
|
) {
|
||||||
|
const debugNode = this.getDebugNode(node);
|
||||||
|
debugNode.drawSpline(knots, mode, knotSize);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"ver": "4.0.23",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "e5842e38-cb01-4432-81b7-6dcc6b33e922",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
import { _decorator, CCFloat, CCInteger, Component, Node, Prefab, randomRangeInt } from 'cc';
|
import { _decorator, CCFloat, CCInteger, Color, Component, Node, Prefab, randomRangeInt } from 'cc';
|
||||||
import ObjectPool from '../Pool/ObjectPool';
|
import { BoosterBase } from '../Booster/BoosterBase';
|
||||||
import { ScoreObject } from '../Environments/ScoreObject';
|
|
||||||
import { EventManger } from './EventManger';
|
|
||||||
import GameEvent from '../Events/GameEvent';
|
|
||||||
import GameState from '../Enum/GameState';
|
import GameState from '../Enum/GameState';
|
||||||
import ScoreType from '../Enum/ScoreType';
|
import ScoreType from '../Enum/ScoreType';
|
||||||
import { BoosterBase } from '../Booster/BoosterBase';
|
import { ScoreObject } from '../Environments/ScoreObject';
|
||||||
|
import GameEvent from '../Events/GameEvent';
|
||||||
|
import Gizmos2D from '../Gizmos/Gizmos2D';
|
||||||
|
import ObjectPool from '../Pool/ObjectPool';
|
||||||
|
import { EventManger } from './EventManger';
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
@ccclass('weightedObject')
|
@ccclass('weightedObject')
|
||||||
|
@ -51,6 +52,17 @@ export class SpawnObjectManager extends Component {
|
||||||
private _boosterSpawned = false;
|
private _boosterSpawned = false;
|
||||||
private _spawnTimeObject = 0;
|
private _spawnTimeObject = 0;
|
||||||
|
|
||||||
|
onFocusInEditor(): void {
|
||||||
|
Gizmos2D.registerDrawGizmos(this.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrawGizmos(): void {
|
||||||
|
for (let i = 0; i < this._spawnPoints.length; i++) {
|
||||||
|
Gizmos2D.beginColor(this.node, new Color(0, 255, 0, 180));
|
||||||
|
Gizmos2D.drawSolidCircle(this.node, this._spawnPoints[i].worldPosition, 15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected onLoad(): void {
|
protected onLoad(): void {
|
||||||
EventManger.instance.on(GameEvent.ObjectRelease, this.onObjectRelease, this);
|
EventManger.instance.on(GameEvent.ObjectRelease, this.onObjectRelease, this);
|
||||||
EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this);
|
EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default interface IPoolable {
|
export default interface IPoolable {
|
||||||
onGet();
|
onGet(): void;
|
||||||
onRelease();
|
onRelease(): void;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue