前期准备工作:

  • 各种类型的触发区模型.vmdl

这里是一个内置的内置的盒子基础模型的文件内容,可以保存为.vmdl查看效果,可以看出文件是kv3格式的,也就意味着可以编写工具来批量生成这些模型文件

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:modeldoc32:version{c5dcef98-b629-46ab-88e3-a17c005c935e} -->
{
	rootNode = 
	{
		_class = "RootNode"
		children = 
		[
			{
				_class = "PhysicsShapeList"
				children = 
				[
					{
						_class = "PhysicsHullFromRender"
						parent_bone = ""
						surface_prop = "default"
						collision_prop = "default"
						faceMergeAngle = 20.0
						maxHullVertices = 32
						optimization_algorithm = "IFR"
					},
				]
				leave_body_collision_unmodified = false
			},
			{
				_class = "RenderMeshList"
				children = 
				[
					{
						_class = "RenderPrimitiveBox"
						name = "box"
						parent_bone = ""
						material_name = "dev/helper/testgrid.vmat"
						origin = [ 0.0, 0.0, 0.0 ]
						angles = [ 0.0, 0.0, 0.0 ]
						max_u = 1.0
						max_v = 1.0
						dimensions = [ 100.0, 100.0, 100.0 ]
						segments_x = 1
						segments_y = 1
						segments_z = 1
					},
				]
			},
		]
		model_archetype = ""
		primary_associated_entity = ""
		anim_graph_name = ""
	}
}

如何创建触发区

在Lua那边编写,下面的代码时ts的语法


//创建触发器实体
const trigger = SpawnEntityFromTableSynchronous('trigger_dota', {
                    targetname : DoUniqueString("testTrigger"),
                    //坐标
                    origin     : origin,
                    //这里时对应锤子编辑器里可以编辑的字段
                    //在锤子中可以编辑的理论都可以在这里设置,如angles,scales,teamnumber,invert_filter_check等等
                    IsRealHero : 1,
                    // 这里就是触发区的模型路径
                    model : "models/cube200.vmdl",
                    wait : 0.1,
                }) as CBaseTrigger;
                
//创建私有的脚本空间,理论应该时可以直接trigger["xxx"] = function的,不过我自己测试没通过
const scope = trigger.GetOrCreatePrivateScriptScope();
scope["OnEnter"] = (arg:
{
    //触发者
    activator:CDOTA_BaseNPC,
    //触发器
    caller:CBaseTrigger
}) => 
{
  print(arg.activator.GetName(), "进入触发区!!!!!!");
}

scope["OnExit"] = (arg:
{
    //触发者
    activator:CDOTA_BaseNPC,
    //触发器
    caller:CBaseTrigger
}) => 
{
  print(arg.activator.GetName(), "离开触发区!!!!!!");
}

//连接触发区触发的io事件
trigger.RedirectOutput("OnStartTouch", "OnEnter", trigger);
//连接触发区离开的io事件
trigger.RedirectOutput("OnEndTouch", "OnExit", trigger);

这样动态触发区的核心就完成了!

查看触发区的坐标和触发区的实际范围,可以在控制台输入showtriggers,触发区会已一个绿色的形状出现,如果在非空地图里查看,可能会看到很多。

小记

但是需要注意处理多个触发区交接的问题, 避免一些逻辑问题,可能需要一个计数来保证触发和离开的处理是安全的

我自己在IcDota中有使用场景,游戏里每隔一段时间或击杀肉山会加载一个世界效果,我称其为动态场景(虽然和动态场景不沾边,哈哈)。

欢迎体验 IcDota