Создание точки появления противников (Устаревшее)
Участников: 2
Страница 1 из 1
Создание точки появления противников (Устаревшее)
Создание точки появления противников (Frags Spawn Point)
На просторах сети наткнулся на этот код и хочу выложить его и вам.
Урок был проверен мною лично на версии NEO 2.5 , все работает отлично, нареканий не имею.
P.S. Одно замечание: точку спауна следует размещать немного выше поверхности на которую будет появляться персонаж, но не очень высоко:
во первых, рост персонажа может быть разным а сам спаун-поинт располагается ровно по середине его общего роста (другими словами, если спаун-поинт разместить на пример на поверхности террейна, то перс появиться по пояс в земельке, и ни куда, как вы понимаете, от туда уйти уже не сможет).
во вторых, если точку спауна разместить довольно высоко, то ваш перс падая вниз, будет очень сильно отскакивать куда попало (в т.ч. и за пределы карты или замкнутые пространства), ударяясь либо об только что созданного перса, либо о землю.
Небольшой совет: можно попытаться немного видоизменить код, а именно внести рандомную составляющую, которая при каждом спауне будет немного изменять координаты позиции спауна по осям X и Y
, тем самым не давая персу валиться на голову только что созданным персам до этого. Хотя и это не панацея, сами догадайтесь почему.
*********************************************************
Что он делает:
Создается SpawnPoint из которого через заданное время выходит заданный противник с заданной фракцией (плохая/хорошая).
Открываем NonCommercialLicense.sln и добавляем новый класс в проект GameEntities. Для этого щелкаем по нему правой кнопкой мыши и выбираем Add > New Item > Class и даем ему имя Spawner.cs или FragsSpawner.cs (на ваше усмотрение).
В новом классе удаляем весь код и ставим этот:
- Код:
// Copyright (C) 2006-2007 NeoAxis Group
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing.Design;
using Engine;
using Engine.EntitySystem;
using Engine.MapSystem;
using Engine.MathEx;
using Engine.PhysicsSystem;
using Engine.Renderer;
using Engine.SoundSystem;
using Engine.Utils;
using GameCommon;
namespace GameEntities
{
///
/// Defines the "SpawnPoint"> entity type.
///
public class SpawnerType : MapObjectType
{
}
public class Spawner : MapObject
{
[FieldSerialize]
AIType aiType;
[FieldSerialize]
FactionType faction;
[FieldSerialize]
UnitType spawnedUnit;
[FieldSerialize]
float spawnTime;
[FieldSerialize]
float spawnRadius;
//counter for remaining time
float spawnCounter;
SpawnerType _type = null; public new SpawnerType Type { get { return _type; } }
[Description("Initial Faction or null for neutral")]
public FactionType Faction
{
get { return faction; }
set { faction = value; }
}
[Description("Time in seconds between spawns")]
[DefaultValue(20.0f)]
public float SpawnTime
{
get { return spawnTime; }
set { spawnTime = value; }
}
[Description("Spawn radius that has to be free of other units")]
[DefaultValue(10.0f)]
public float SpawnRadius
{
get { return spawnRadius; }
set { spawnRadius = value; }
}
[Description("UnitType that will be spawned")]
public UnitType SpawnedUnit
{
get { return spawnedUnit; }
set { spawnedUnit = value; }
}
[Description("Default AI for this unit or none for empty unit")]
public AIType AIType
{
get { return aiType; }
set { aiType = value; }
}
protected override void OnPostCreate(bool loaded)
{
base.OnPostCreate(loaded);
spawnCounter = 0.0f;
AddTimer();
}
protected override void OnTick()
{
base.OnTick();
spawnCounter += TickDelta;
if (spawnCounter >= SpawnTime) //time to do it
{
spawnCounter = 0.0f;
if (!isSpawnPositionFree()) return;
Unit i = (Unit)Entities.Instance.Create(SpawnedUnit, Parent);
if (AIType != null)
{
i.InitialAI = AIType;
}
if (i == null) return;
i.Position = FindFreePositionForUnit(i, Position);
i.Rotation = Rotation;
if (Faction != null)
{
i.InitialFaction = Faction;
}
i.PostCreate();
}
}
Vec3 FindFreePositionForUnit(Unit unit, Vec3 center)
{
Vec3 volumeSize = unit.MapBounds.GetSize() + new Vec3(2, 2, 0);
for (float zOffset = 0; ; zOffset += .3f)
{
for (float radius = 3; radius < 8; radius += .6f)
{
for (float angle = 0; angle < MathFunctions.PI * 2; angle += MathFunctions.PI / 32)
{
Vec3 pos = center + new Vec3(MathFunctions.Cos(angle),
MathFunctions.Sin(angle), 0) * radius + new Vec3(0, 0, zOffset);
Bounds volume = new Bounds(pos);
volume.Expand(volumeSize * .5f);
Body[] bodies = PhysicsWorld.Instance.VolumeCast(
volume, (int)ContactGroup.CastOnlyContact);
if (bodies.Length == 0)
return pos;
}
}
}
}
bool isSpawnPositionFree()
{
bool returnValue = true;
Map.Instance.GetObjects(new Sphere(Position, SpawnRadius),
GameFilterGroups.UnitFilterGroup, delegate(MapObject mapObject)
{
Unit unit = mapObject as Unit;
//if there is atleast one then we won't spawn
if (unit != null)
{
returnValue = false;
}
});
/*
foreach (Entity obj in Entities.Instance.EntitiesCollection)
{
Unit un = obj as Unit;
if (un != null)
{
if ((un.Position - Position).LengthFast() < SpawnRadius)
{
returnValue = false;
}
}
}
*/
return returnValue;
}
}
}
Теперь создадим в Редакторе Ресурсов в папке Special новый *.Type, выбираем для него класс Spawner (или FragsSpawner) и даем имя тоже Spawner (или FragsSpawner). Переходим в режим редактирования и указываем ему меш в Types > Base > InvisiblePoint.mesh .
Также выставляем свойство OnlyForEditor у присоединенного объекта в True.
Далее мы должны добавить новый тип в список разрешенных для показа в Редакторе карт. Для этого мы в Spawner.Type ставим параметр AllowEditorCreate в True.
Теперь перейдя в редактор карт в папке Special мы можем найти наш новый объект. Мы можем поставить его на карту и настроить требуемые нам параметры появления игровых противников самостоятельно.
Запускаем карту и тестим.
Успешного вам геймдева!
Re: Создание точки появления противников (Устаревшее)
Вот код, работающий в версии 3.5
- Код:
// Copyright (C) NeoAxis Group Ltd. This is part of NeoAxis 3D Engine SDK.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Design;
using System.ComponentModel;
using System.IO;
using Engine;
using Engine.EntitySystem;
using Engine.MapSystem;
using Engine.Utils;
using Engine.SoundSystem;
using Engine.MathEx;
using Engine.FileSystem;
using ProjectCommon;
using Engine.PhysicsSystem;
namespace ProjectEntities
{
/// <summary>
/// Defines the <see cref="Item"/> entity type.
/// </summary>
public class SpawnerType : MapObjectType
{
}
/// <summary>
/// Items which can be picked up by units. Med-kits, weapons, ammunition.
/// </summary>
public class Spawner : MapObject
{
static List<Spawner> instances = new List<Spawner>();
[FieldSerialize]
AIType aiType;
[FieldSerialize]
FactionType faction;
[FieldSerialize]
UnitType spawnedUnit;
[FieldSerialize]
float spawnTime;
[FieldSerialize]
float spawnRadius;
//counter for remaining time
float spawnCounter;
SpawnerType _type = null; public new SpawnerType Type { get { return _type; } }
[Description("Initial Faction or null for neutral")]
public FactionType Faction
{
get { return faction; }
set { faction = value; }
}
[Description("Time in seconds between spawns")]
[DefaultValue(20.0f)]
public float SpawnTime
{
get { return spawnTime; }
set { spawnTime = value; }
}
[Description("Spawn radius that has to be free of other units")]
[DefaultValue(10.0f)]
public float SpawnRadius
{
get { return spawnRadius; }
set { spawnRadius = value; }
}
[Description("UnitType that will be spawned")]
public UnitType SpawnedUnit
{
get { return spawnedUnit; }
set { spawnedUnit = value; }
}
[Description("Default AI for this unit or none for empty unit")]
public AIType AIType
{
get { return aiType; }
set { aiType = value; }
}
/// <summary>Overridden from <see cref="Engine.EntitySystem.Entity.OnPostCreate(Boolean)"/>.</summary>
protected override void OnPostCreate(bool loaded)
{
base.OnPostCreate(loaded);
SubscribeToTickEvent();
instances.Add(this);
spawnCounter = 0.0f;
}
/// <summary>Overridden from <see cref="Engine.EntitySystem.Entity.OnTick()"/>.</summary>
protected override void OnTick()
{
base.OnTick();
spawnCounter += TickDelta;
if (spawnCounter >= SpawnTime) //time to do it
{
spawnCounter = 0.0f;
if (!isSpawnPositionFree()) return;
Unit i = (Unit)Entities.Instance.Create(SpawnedUnit, Parent);
if (AIType != null)
{
i.InitialAI = AIType;
}
if (i == null) return;
i.Position = FindFreePositionForUnit(i, Position);
i.Rotation = Rotation;
if (Faction != null)
{
i.InitialFaction = Faction;
}
i.PostCreate();
}
}
void Print(string Text)
{
if (EngineConsole.Instance == null) return;
EngineConsole.Instance.Print(Text);
}
protected override void Client_OnTick()
{
base.Client_OnTick();
spawnCounter += TickDelta;
if (spawnCounter >= SpawnTime) //time to do it
{
spawnCounter = 0.0f;
if (!isSpawnPositionFree()) return;
Unit i = (Unit)Entities.Instance.Create(SpawnedUnit, Parent);
if (AIType != null)
{
i.InitialAI = AIType;
}
if (i == null) return;
i.Position = FindFreePositionForUnit(i, Position);
i.Rotation = Rotation;
if (Faction != null)
{
i.InitialFaction = Faction;
}
i.PostCreate();
}
}
Vec3 FindFreePositionForUnit(Unit unit, Vec3 center)
{
Vec3 volumeSize = unit.MapBounds.GetSize() + new Vec3(2, 2, 0);
for (float zOffset = 0; ; zOffset += .3f)
{
for (float radius = 3; radius < 8; radius += .6f)
{
for (float angle = 0; angle < MathFunctions.PI * 2; angle += MathFunctions.PI / 32)
{
Vec3 pos = center + new Vec3(MathFunctions.Cos(angle),
MathFunctions.Sin(angle), 0) * radius + new Vec3(0, 0, zOffset);
Bounds volume = new Bounds(pos);
volume.Expand(volumeSize * .5f);
Body[] bodies = PhysicsWorld.Instance.VolumeCast(
volume, (int)ContactGroup.CastOnlyContact);
if (bodies.Length == 0)
return pos;
}
}
}
}
bool isSpawnPositionFree()
{
bool returnValue = true;
Map.Instance.GetObjects(new Sphere(Position, SpawnRadius),
MapObjectSceneGraphGroups.UnitGroupMask, delegate(MapObject mapObject)
{
Unit unit = (Unit)mapObject;
//if there is atleast one then we won't spawn
if (unit != null)
{
returnValue = false;
}
});
/*
foreach (Entity obj in Entities.Instance.EntitiesCollection)
{
Unit un = obj as Unit;
if (un != null)
{
if ((un.Position - Position).LengthFast() < SpawnRadius)
{
returnValue = false;
}
}
}
*/
return returnValue;
}
}
}
Gedifilyte- Сообщения : 2
Рейтинг : 1724
Репутация : 0
Дата регистрации : 2019-08-12
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
|
|
Пт Май 08, 2020 6:18 pm автор Gedifilyte
» Создание точки появления противников (Устаревшее)
Сб Дек 14, 2019 2:34 am автор Gedifilyte
» Создание инвентаря (устаревшее)
Пт Апр 13, 2018 7:43 pm автор Eris
» Программное создание Mesh
Пн Фев 05, 2018 12:05 am автор Eris
» Помогите !!! (вопросы, советы, обсуждения)
Вт Июн 06, 2017 11:39 am автор Zhuravlev Yuri
» Редакторы карт и ресурсов
Ср Май 24, 2017 10:23 pm автор Чумной Доктор
» Создание "Игрового типа" (GameType)
Ср Апр 05, 2017 2:19 am автор Filat
» Экспорт из 3ds Max
Сб Мар 11, 2017 12:22 pm автор Uggo
» Создание "Выбор персонажа"
Сб Фев 25, 2017 11:32 am автор Filat