///<summary>キャラクター生成</summary> static public MapCharacter createCharacter(MapFileData.Character aData) { MapCharacter tCharacter = MyBehaviour.createObjectFromResources <MapCharacter>(MyMap.mMapResourcesDirectory + "/character/" + aData.mPath); //名前 tCharacter.mName = aData.mName; tCharacter.name = "character:" + aData.mName; //向き tCharacter.mCharacterRenderBehaviour.mImage.setDirection(aData.mDirection); //ai tCharacter.setAi(createAi(aData.mAi)); //state tCharacter.transitionState(createState(aData.mState)); //movingData tCharacter.mMovingData = new MovingData(); tCharacter.mMovingData.mSpeed = aData.mMoveSpeed; Vector3 tColliderSize = tCharacter.mEntityPhysicsBehaviour.mAttriubteCollider.minimumCircumscribedCube(); tCharacter.mMovingData.mDeltaDistance = Mathf.Min(tColliderSize.x, tColliderSize.z); //speaker if (aData.mIsSpeaker) { MapKeyEventSpeaker tSpeaker = tCharacter.mEntityPhysicsBehaviour.mAttriubteCollider.gameObject.AddComponent <MapKeyEventSpeaker>(); tSpeaker.mBehaviour = tCharacter; tSpeaker.mSpeakDefault = aData.mSpeakDefault; tSpeaker.mSpeakFromUp = aData.mSpeakFromUp; tSpeaker.mSpeakFromDown = aData.mSpeakFromDown; tSpeaker.mSpeakFromLeft = aData.mSpeakFromLeft; tSpeaker.mSpeakFromRight = aData.mSpeakFromRight; } return(tCharacter); }
// Use this for initialization void Start() { Arg tArg = MySceneManager.getArg("map"); mMap = LocalMapCreater.create(tArg.get <string>("mapName")); //ユーザ MapCharacter tPlayer = MapCharacterCreater.create("player", "player/player", new Direction(tArg.get <string>("direction")), "player"); tPlayer.setPosition(new Vector2(tArg.get <int>("positionX"), tArg.get <int>("positionY"))); mMap.addCharacter(tPlayer); GameObject tCamera = GameObject.Find("MapCamera"); tCamera.transform.parent = tPlayer.transform; tCamera.transform.localPosition = new Vector3(0, 0, -100); //ui MySceneManager.openScene("mapUi", new Arg()); Subject.addObserver(new Observer("mapUi", (message) => { if (message.name == "menuButton") { Debug.Log("open menu"); } }, "map")); }
/// <summary>正面の話しかけるor調べる範囲内のspeakerを取得</summary> static public List <MapSpeaker> getFrontSpeakers(MapCharacter aCharacter) { Collider tCharacterCollider = aCharacter.mEntityPhysicsBehaviour.mAttriubteCollider; Vector3 tColliderHalfSize = tCharacterCollider.minimumCircumscribedCube() / 2f; //キャラが向いている方向 float tAngle = new Vector2(-1, 0).corner(new Vector2(aCharacter.mMovingData.mLastDirection.x, aCharacter.mMovingData.mLastDirection.z)); //調べる範囲 float tYRate = Mathf.Abs(Mathf.Abs(tAngle) - 90) / 90f; Vector3 tSearchSize = new Vector3(tColliderHalfSize.x * (1 - tYRate) + tColliderHalfSize.z * tYRate + aCharacter.mMovingData.mSpeakDistance, tColliderHalfSize.y * 2, tColliderHalfSize.x * tYRate + tColliderHalfSize.z * (1 - tYRate)); //範囲内のcolliderを取得 Collider[] tColliders = Physics.OverlapBox(tCharacterCollider.transform.position + tCharacterCollider.getCenter() + aCharacter.mMovingData.mLastDirection.normalized * tSearchSize.x / 2f, tSearchSize / 2f, Quaternion.Euler(0, tAngle, 0)); //speakerのみ抽出 List <MapSpeaker> tSpeakers = new List <MapSpeaker>(); MapSpeaker tSpeaker; foreach (Collider tCollider in tColliders) { tSpeaker = tCollider.GetComponent <MapSpeaker>(); if (tSpeaker == null) { continue; } tSpeakers.Add(tSpeaker); } return(tSpeakers); }
/// <summary>指定キャラがこのtriggerを発火させるか(trueなら発火)</summary> public bool isTriggerCharacter(MapCharacter aCharacter) { //AI操作でないなら発火しない if (aCharacter.getOperation() != MapCharacter.Operation.free) { return(false); } foreach (string tKeyName in mTriggerKey) { //プレイヤーか if (tKeyName == "player") { if (aCharacter.isPlayer()) { return(true); } continue; } //名前が一致するか if (tKeyName == aCharacter.mName) { return(true); } } return(false); }
public override bool canReply(MapCharacter aCharacter, MapEventSystem aEventSystem) { if (mSpeakDefault != "") { return(true); } return(getAnswerKey(aCharacter) != ""); }
public override void speak(MapCharacter aCharacter, MapEventSystem aEventSystem) { if (mAnimating) { return; } shake(); }
void Start() { mapCharacter = Instantiate(mapCharacter_to_instantiate); mapCharacter.character = realCharacter.gameObject; mapCharacter.transform.SetParent(transform); Events.OnAddEnemy += OnAddEnemy; }
public virtual bool ContestingFallMovement(MapCharacter character) { if (CollisionSensor.CheckSensorCollision(character.CollisionSensors[SensorType.Bottom], collisionSensors[SensorType.Top])) { return true; } return false; }
void OnAddEnemy(Transform t) { MapCharacter mapCharacter = Instantiate(mapEnemy_to_instantiate); mapCharacter.character = t.gameObject; mapCharacter.transform.SetParent(transform); mapEnemy.Add(mapCharacter); }
static public MapCharacter create(string aAiName, string aSpriteFileName, Direction aDirection, string aName = "", Vector2?aColliderSize = null) { if (aColliderSize == null) { aColliderSize = new Vector2(0.6f, 0.3f); } //画像 Sprite tOrigen = Resources.Load <Sprite>("Sprites/character/" + aSpriteFileName); Sprite[,] tSprites = new Sprite[3, 4]; for (int x = 0; x < 3; x++) { for (int y = 0; y < 4; y++) { tSprites[x, y] = SpriteCutter.Create(tOrigen.texture, new Rect(x * 100, y * 100, 100, 100), new Vector2(0.5f, 0f), 80); } } Dictionary <string, List <Sprite> > tDic = new Dictionary <string, List <Sprite> >(); tDic["standUp"] = new List <Sprite>() { tSprites[1, 0] }; tDic["standDown"] = new List <Sprite>() { tSprites[1, 3] }; tDic["standLeft"] = new List <Sprite>() { tSprites[1, 2] }; tDic["standRight"] = new List <Sprite>() { tSprites[1, 1] }; tDic["moveUp"] = new List <Sprite>() { tSprites[0, 0], tSprites[1, 0], tSprites[2, 0], tSprites[1, 0] }; tDic["moveDown"] = new List <Sprite>() { tSprites[0, 3], tSprites[1, 3], tSprites[2, 3], tSprites[1, 3] }; tDic["moveLeft"] = new List <Sprite>() { tSprites[0, 2], tSprites[1, 2], tSprites[2, 2], tSprites[1, 2] }; tDic["moveRight"] = new List <Sprite>() { tSprites[0, 1], tSprites[1, 1], tSprites[2, 1], tSprites[1, 1] }; MapCharacter tCharacter = MyBehaviour.create <MapCharacter>(); tCharacter.init(aAiName, tDic, (Vector2)aColliderSize, aDirection, aName); return(tCharacter); }
public override void speak(MapCharacter aCharacter, MapEventSystem aEventSystem) { string mAnswerKey = getAnswerKey(aCharacter); if (mAnswerKey == "") { return; } aEventSystem.addEvent(mAnswerKey, aCharacter, mBehaviour, mCollider); }
/// <summary>trigger衝突状況データを初期化</summary> static public void initTriggerDataOfMovingData(MapCharacter aCharacter) { List <MapTrigger> tTriggers = getCollidedTriggers(aCharacter); foreach (MapTrigger tTrigger in tTriggers) { tTrigger.existInner(aCharacter); } aCharacter.mMovingData.mCollidedTriggers = tTriggers; }
/// <summary> /// イベントを待機リストに追加 /// </summary> /// <returns>イベント発火可能ならtrue</returns> /// <param name="aEventKey">worldが持つイベントのKey</param> /// <param name="aInvoker">起動者</param> /// <param name="aInvoked">イベント所持者</param> /// <param name="aInvokedCollider">イベント所持者のcollider</param> public bool addEvent(string aEventKey, MapCharacter aInvoker, MapBehaviour aInvoked, Collider aInvokedCollider) { Operator tOperator = new Operator(this, mWorld.mEvents[aEventKey]); tOperator.mInvoker = aInvoker; tOperator.mInvoked = aInvoked; tOperator.mInvokedCollider = aInvokedCollider; return(addOperator(tOperator)); }
/// <summary> /// イベントを待機リストに追加 /// </summary> /// <returns>イベント発火可能ならtrue</returns> /// <param name="aEvent">実行するイベント</param> /// <param name="aInvoker">起動者</param> /// <param name="aInvoked">イベント所持者</param> /// <param name="aInvokedCollider">イベント所持者のcollider</param> public bool addEvent(MapEvent aEvent, MapCharacter aInvoker, MapBehaviour aInvoked, Collider aInvokedCollider) { Operator tOperator = new Operator(this, aEvent); tOperator.mInvoker = aInvoker; tOperator.mInvoked = aInvoked; tOperator.mInvokedCollider = aInvokedCollider; return(addOperator(tOperator)); }
///<summary>移動開始前に移動データ初期化</summary> public static void initFrameMovingData(MapCharacter aCharacter) { //移動可能距離 aCharacter.mMovingData.mRemainingDistance = aCharacter.mMovingData.mSpeed * Time.deltaTime; if (aCharacter.mMovingData.mMaxMoveDistance < aCharacter.mMovingData.mRemainingDistance) { aCharacter.mMovingData.mRemainingDistance = aCharacter.mMovingData.mMaxMoveDistance; } //移動前の座標 aCharacter.mMovingData.mPrePosition = aCharacter.mMapPosition; }
public override void update(MapCamera aParent) { if (mPlayer == null) { mPlayer = aParent.mWorld.getPlayer(); } if (mPlayer == null) { return; } aParent.position2D = mPlayer.mMapPosition.renderPosition.toVector2(); }
/// <summary>何かに衝突しているならtrue</summary> public static bool isCollided(MapCharacter aCharacter) { mCharacter = aCharacter; mCollider = aCharacter.mEntityPhysicsBehaviour.mAttriubteCollider; mAttribute = aCharacter.mEntityPhysicsBehaviour.mAttribute; MapPhysics.CollisionType tType; RaycastHit[] tHits = castAttribute(new Vector3(0, 1, 0), 0, out tType); mCharacter = null; mCollider = null; mAttribute = null; return(tType == MapPhysics.CollisionType.collide); }
/// <summary>trigger内で移動した</summary> public override void moved(MapCharacter aCharacter, MapEventSystem aEventSystem) { if (!isTriggerCharacter(aCharacter)) { return; } if (mMovedKey == "" || mMovedKey == null) { return; } aEventSystem.addEvent(mMovedKey, aCharacter, mBehaviour, mCollider); }
/// <summary>話しかけるor調べる処理</summary> static public void speak(MapCharacter aCharacter, MapEventSystem aEventSystem) { foreach (MapSpeaker tSpeaker in getTargetSpeakers(aCharacter)) { //応答不可 if (!tSpeaker.canReply(aCharacter, aEventSystem)) { continue; } tSpeaker.speak(aCharacter, aEventSystem); return; } }
public override void HandleCollisions(MapCharacter character) { if (CollisionSensor.CheckSensorCollision(character.CollisionSensors[SensorType.Bottom], collisionSensors[SensorType.Top]) && character.CurrentAction == MapCharacterAction.Fall) { character.CurrentAction = MapCharacterAction.Land; GameClass.SoundManager.PlaySoundEffect("Audio/land"); character.Velocity = Vector2.Zero; character.InAir = false; character.Position = new Vector2(character.Position.X, (collisionBox.Rectangle.Top - (character.CurrentCollisionBox.Rectangle.Height / 2) - character.CurrentCollisionBox.Offset.Y + 1)); } base.HandleCollisions(character); }
/// <summary> /// マップ移動イベントの移動後のイベント処理実行 /// </summary> /// <param name="aEvent">マップ移動イベント</param> public void addMoveMapEventEndSide(MapEventMoveMapEndSide aEvent, MapCharacter aInvoker) { MapEventRoot tRoot = new MapEventRoot(new List <string>(), true, false, aEvent); Operator tOperator = new Operator(this, aEvent); tOperator.mInvoker = aInvoker; if (addOperator(tOperator)) { runWaitingEvents(); } else { throw new System.Exception("MapEventSystem : マップ移動後イベントの実行に失敗"); } }
///<summary>キャラクターを生成してworldに追加</summary> static private MapCharacter buildCharacter(MapFileData.Character aData) { //生成フラグ確認 if (!flagCreate(aData)) { return(null); } MapCharacter tCharacter = createCharacter(aData); tCharacter.mFileData = aData; tCharacter.transform.SetParent(mWorld.mCharacterContainer.transform, false); tCharacter.mMapPosition = new MapPosition(aData.mPosition); tCharacter.changeLayer(MyMap.mStratumLayerNum[Mathf.FloorToInt(aData.mY)]); mWorld.mCharacters.Add(tCharacter); return(tCharacter); }
/// <summary>マップ移動</summary> public void moveMap(MapEventMoveMap aMoveEvent) { //マップ再生成 load(aMoveEvent.mMapPath); aMoveEvent.mEndSide.mEntranceData = mWorld.mFileData.mEntrances[aMoveEvent.mEndSide.mEntrance]; //移動先座標計算 MapCharacter tCharacter = MapWorldFactory.createCharacter(mPlayerData); aMoveEvent.mEndSide.calculatePositionFromPercentagePosition(tCharacter.mEntityPhysicsBehaviour.mAttriubteCollider); tCharacter.delete(); //プレイヤー追加 mPlayerData.mPosition = aMoveEvent.mEndSide.mPosition; mPlayerData.mDirection = aMoveEvent.mPlayerDirection; MapWorldFactory.addCharacter(mPlayerData, mWorld); //マップ移動後イベント実行 mWorld.mEventSystem.addMoveMapEventEndSide(aMoveEvent.mEndSide, mWorld.getPlayer()); mWorld.updateWorld(); }
/// <summary>characterの保存データ生成</summary> static public MapSaveFileData.Character saveCharacter(MapCharacter aCharacter) { MapSaveFileData.Character tSaveData = new MapSaveFileData.Character(aCharacter.mFileData); //座標 MapPosition tPosition = aCharacter.mMapPosition; tSaveData.mPosition = tPosition.vector; //createFlag tSaveData.mCreateFlag = null; //向き tSaveData.mDirection = aCharacter.mCharacterImage.getDirection(); //ai tSaveData.mAiString = aCharacter.saveAi(); //state tSaveData.mStateString = aCharacter.saveState(); return(tSaveData); }
/// <summary>話しかけるor調べる対象となるspeakerを優先順位順で取得</summary> static public List <MapSpeaker> getTargetSpeakers(MapCharacter aCharacter) { //配置後全く移動していない場合は話しかけれない if (aCharacter.mMovingData.mLastDirection == Vector3.zero) { return(new List <MapSpeaker>()); } List <MapSpeaker> tSpeakers = getFrontSpeakers(aCharacter); List <MapSpeaker> tTargets = new List <MapSpeaker>(); float tCorner; List <float> tCornerList = new List <float>(); Vector3 tSeacherPoint = aCharacter.mEntityPhysicsBehaviour.mAttriubteCollider.getCenter(); //話しかけるキャラのcolliderの中心点 Vector3 tClosestPoint; Vector2 tCharacterDirection = new Vector2(aCharacter.mMovingData.mLastDirection.x, aCharacter.mMovingData.mLastDirection.z); //キャラが向いている方向 foreach (MapSpeaker tSpeaker in tSpeakers) { //tSeacherPointからspeakerのcolliderへの最寄り点 tClosestPoint = tSpeaker.mCollider.ClosestPoint(tSeacherPoint); //キャラの向きとspeakerへの方向のなす角 tCorner = tCharacterDirection.cornerAbs(new Vector2(tClosestPoint.x - tSeacherPoint.x, tClosestPoint.z - tSeacherPoint.z)); //対象のリストに追加 bool tAdd = false; for (int i = 0; i < tCornerList.Count; ++i) { if (tCornerList[i] < tCorner) { continue; } tCornerList.Insert(i, tCorner); tTargets.Add(tSpeaker); tAdd = true; break; } if (!tAdd) { tCornerList.Add(tCorner); tTargets.Add(tSpeaker); } } return(tTargets); }
///<summary>キャラを移動させる(同フレームでさらに移動可能ならtrue)</summary> public static bool moveCharacter(MapCharacter aCharacter) { if (aCharacter.mMovingData.mDirection == Vector3.zero) { //移動しない場合 aCharacter.mMovingData.mRemainingDistance = 0; return(false); } //移動処理前の座標を記録 aCharacter.mMovingData.mDeltaPrePosition = aCharacter.mMapPosition; //最後の移動方向記録 aCharacter.mMovingData.mLastDirection = aCharacter.mMovingData.mDirection; //移動処理で使うデータ収集・記録 mCharacter = aCharacter; mAttribute = aCharacter.mEntityPhysicsBehaviour.mAttribute; mCollider = mAttribute.mCollider; mDirection = aCharacter.mMovingData.mDirection.normalized; mDeltaDistance = aCharacter.mMovingData.mDeltaDistance; if (kMaxDeltaDistance < mDeltaDistance) { mDeltaDistance = kMaxDeltaDistance; } mRemainingDistance = mCharacter.mMovingData.mRemainingDistance; //移動させる MoveResult tResult = moveDelta(); if (tResult.mCollisionType == MapPhysics.CollisionType.pass) { } else if (tResult.mCollisionType == MapPhysics.CollisionType.collide) { mCharacter.mMovingData.mRemainingDistance = 0; return(false); } else if (tResult.mCollisionType == MapPhysics.CollisionType.stop) { mCharacter.mMovingData.mRemainingDistance = 0; return(false); } //残りの移動距離を減算 mCharacter.mMovingData.mRemainingDistance -= mDeltaDistance; return(mCharacter.mMovingData.mRemainingDistance > 0); }
///調べられた public void searched(MapCharacter aCharacter) { //距離を測る ColliderDistance2D tDistance = Physics2D.Distance(gameObject.GetComponents <Collider2D>()[0], aCharacter.gameObject.GetComponents <Collider2D>()[0]); //調べた方向 Direction tDirection = new Direction(tDistance.normal); //発火するイベント MapEvent tEvent = getEvent(tDirection); if (tEvent == null) { return; } Subject.sendMessage(new Message("mapEvent", new Arg(new Dictionary <string, object>() { { "event", tEvent } }))); }
/// <summary>指定名のキャラのAIをジャック(予約名考慮)(ジャック成功時もしくは指定名のキャラが存在しない時true)</summary> public bool jack(string aName) { //ジャックするキャラ取得 MapCharacter tCharacter = null; if (aName == "invoker") { tCharacter = mInvoker; } else if (aName == "invoked" && mInvoked is MapCharacter) { tCharacter = (MapCharacter)mInvoked; } else if (aName == "player") { tCharacter = parent.mWorld.getPlayer(); } else { tCharacter = parent.mWorld.getCharacter(aName); } if (tCharacter == null) { return(true); } //ジャックスする MapCharacter.JackedAi tAi = tCharacter.jack(); if (tAi != null) { //ジャックできた mAiDic.Add(aName, tAi); mAiDic.Add(tCharacter.mName, tAi); return(true); } //ジャックできなかった場合 if (mAiDic.ContainsKey(aName)) { return(true);//既にジャック済み } //ジャック失敗 return(false); }
/// <summary>衝突したtriggerを発火させる</summary> static public void trigger(MapCharacter aEntity, MapEventSystem aEventSystem) { bool tMoved = aEntity.mMovingData.mPrePosition != aEntity.mMapPosition; List <MapTrigger> tCollidedTriggers = getCollidedTriggers(aEntity); foreach (MapTrigger tTrigger in tCollidedTriggers) { int tCount = aEntity.mMovingData.mCollidedTriggers.Count; bool tFind = false; for (int i = 0; i < tCount; ++i) { if (aEntity.mMovingData.mCollidedTriggers[i] != tTrigger) { continue; } if (tMoved) { tTrigger.moved(aEntity, aEventSystem); //内部移動 } else { tTrigger.stay(aEntity, aEventSystem); //内部停止 } aEntity.mMovingData.mCollidedTriggers.RemoveAt(i); tFind = true; break; } if (tFind) { continue; } tTrigger.enter(aEntity, aEventSystem);//侵入 } foreach (MapTrigger tTrigger in aEntity.mMovingData.mCollidedTriggers) { tTrigger.exit(aEntity, aEventSystem);//撤退 } aEntity.mMovingData.mCollidedTriggers = tCollidedTriggers; }
void Update() { mapCharacter.transform.localPosition = GetMapPosition(mapCharacter.character.transform.position); MapCharacter mapCharacterToDestroy = null; foreach (MapCharacter enemyMapCharacter in mapEnemy) { if (enemyMapCharacter.character == null) { mapCharacterToDestroy = enemyMapCharacter; } else { enemyMapCharacter.transform.localPosition = GetMapPosition(enemyMapCharacter.character.transform.position); } } if (mapCharacterToDestroy != null) { mapEnemy.Remove(mapCharacterToDestroy); Destroy(mapCharacterToDestroy.gameObject); } }
public override void HandleCollisions(MapCharacter character) { if (character.CurrentAction != MapCharacterAction.Death) { if (CollisionSensor.CheckSensorCollision(character.CollisionSensors[SensorType.Bottom], collisionBox.Rectangle)) { if (character.CurrentAction == MapCharacterAction.Fall) { character.InAir = false; character.Velocity = velocity; character.CurrentAction = MapCharacterAction.Land; GameClass.SoundManager.PlaySoundEffect("Audio/land"); character.Position = new Vector2(character.Position.X, (collisionBox.Rectangle.Top - (character.CurrentCollisionBox.Rectangle.Height / 2) - character.CurrentCollisionBox.Offset.Y)); } } if (CollisionSensor.CheckSensorCollision(character.CollisionSensors[SensorType.Left], collisionBox.Rectangle)) { character.Position = new Vector2(character.Position.X + character.CollisionSensors[SensorType.Left].SensorDepth, character.Position.Y); character.Velocity = new Vector2(0, character.Velocity.Y); } if (CollisionSensor.CheckSensorCollision(character.CollisionSensors[SensorType.Right], collisionBox.Rectangle)) { character.Position = new Vector2(character.Position.X - character.CollisionSensors[SensorType.Right].SensorDepth, character.Position.Y); character.Velocity = new Vector2(0, character.Velocity.Y); } if (CollisionSensor.CheckSensorCollision(character.CollisionSensors[SensorType.Top], collisionBox.Rectangle)) { character.Position = new Vector2(character.Position.X, character.Position.Y + character.CollisionSensors[SensorType.Top].SensorDepth); character.CurrentAction = MapCharacterAction.Fall; character.Velocity = new Vector2(character.Velocity.X, 0); } } base.HandleCollisions(character); }
/// <summary> /// エンカウントのカウントを進める /// </summary> /// <returns>エンカウントした場合はtrue</returns> /// <param name="aCharacter">Player Character</param> /// <param name="aWorld">MapWorld</param> static private bool encountCount(MapCharacter aCharacter, MapWorld aWorld) { Vector3Int tPosition = aCharacter.mFootCellPosition; MapCell tCell = aWorld.mCells[tPosition.x, tPosition.y, tPosition.z]; //エンカウントしないマス if (tCell.mEncountKey == null || tCell.mEncountKey == "") { return(false); } //移動距離 float tDeltaDistance = (aCharacter.mMovingData.mDeltaPrePosition.vector2 - aCharacter.mMapPosition.vector2).magnitude; if (!aWorld.mMap.mEncountSystem.count(tCell.mEncountFrequency * tDeltaDistance, tCell.mEncountKey)) { return(false); } //エンカウントした aCharacter.mMovingData.mRemainingDistance = 0; aCharacter.mMovingData.mSpeak = false; return(true); }
public FlexibleState(MapCharacter aParent) : base(aParent) { }
public virtual void HandleCollisions(MapCharacter character) { }