20210415のC#に関する記事は6件です。

[Unity] 現在のECS環境でシンプルな Boids Simulation を書く

ずいぶん前に Unity ECS の勉強をしたときにhecomiさんのBoidsシミュレーションを題材に使わせていただいたのですが、UnityのDOTS環境がどんどん変わっていって現行環境に合わせて大規模なリファクタリングが必要になったので、その際の情報を備忘録としてまとめます。 環境 (2021/4/15 時点) Unity 2020.3.4f Hybrid Renderer 0.11.0-preview.42 Entities 0.17.0.preview.41 当方の実装結果 GitHub 現在のECSの書き方 ▽Prefab Entity の準備 public class Bootstrap : MonoBehaviour { public static Bootstrap Instance { get; private set; } public static Param Param { get { return Instance.param; } } // Inspector で Prefab を設定しておく [SerializeField] GameObject prefab_obj; // Prefab Entity 保持用の変数 private Entity prefab_entity; // Boid の全体数の管理用 private int n_boid; void Awake() { Instance = this; } public void Start() { var world = World.DefaultGameObjectInjectionWorld; var manager = world.EntityManager; // convert prefab_obj -> prefab_entity prefab_entity = GameObjectConversionUtility.ConvertGameObjectHierarchy( prefab_obj, GameObjectConversionSettings.FromWorld(world, null) ); // add user defined component manager.AddComponent<BoidPrefabType>(prefab_entity); // Prefabであることを示す空のComponent manager.AddComponent<Scale>(prefab_entity); manager.AddComponent<Velocity>(prefab_entity); manager.AddComponent<Acceleration>(prefab_entity); manager.AddComponent<NeighborsEntityBuffer>(prefab_entity); n_boid = 0; } } たびたび Hybrid Renderer が使用する Component が追加されているようで、自力で ArchType を組み立てるやり方だと、適当にアップグレードしたときに描画されなくなります。 また、 Hybrid Renderer も設定(V2を使うか否か)によって動かない場合があり、原因の特定に手間取りました。 公式サンプルもそうですが、Hybrid ECS用のAPIを活用してGameObjectから必要な ArchType を構築すれば上記の仕様変更にも自動的に追従できることになり、ほんの少しリスクが減ります。 PrefabなのでSystemの操作対象に紛れ込まないよう、空のコンポーネント BoidPrefabType をつけています。 ▽Entityの生成、破棄 public class Bootstrap : MonoBehaviour { public static Bootstrap Instance { get; private set; } public static Param Param { get { return Instance.param; } } [SerializeField] public float boidScale = 1.0f; [SerializeField] public Param param; [SerializeField] GameObject prefab_obj; private Entity prefab_entity; private int n_boid; private Unity.Mathematics.Random random; /* 略 */ void UpdateBoidNum(int n_tgt) { if (n_tgt < 0) return; var manager = World.DefaultGameObjectInjectionWorld.EntityManager; int n_diff = n_tgt - n_boid; if (n_diff > 0) { Debug.Log($"update boids num: add {n_diff} boids."); var scale = this.boidScale; var initSpeed = this.param.initSpeed; for (int i = 0; i < n_diff; i++) { var entity = manager.Instantiate(prefab_entity); // BoidPrefabType を BoidType に付け替え manager.RemoveComponent<BoidPrefabType>(entity); manager.AddComponent<BoidType>(entity); // 適当に値を設定 manager.SetComponentData(entity, new Translation { Value = this.random.NextFloat3(1f) }); manager.SetComponentData(entity, new Rotation { Value = quaternion.identity }); manager.SetComponentData(entity, new Scale { Value = scale }); manager.SetComponentData(entity, new Velocity { Value = this.random.NextFloat3Direction() * initSpeed }); manager.SetComponentData(entity, new Acceleration { Value = float3.zero }); } } if (n_diff < 0) { int n_delete = -n_diff; Debug.Log($"update boids num: remove {n_delete} boids."); var entity_query = manager.CreateEntityQuery(new EntityQueryDesc { All = new[] { ComponentType.ReadOnly<BoidType>() } }); var entities = entity_query.ToEntityArray(Allocator.Temp); manager.DestroyEntity(new NativeSlice<Entity>(entities, n_tgt)); entities.Dispose(); } n_boid = n_tgt; } } Entityの生成については元の実装と大して違いはありません。 破棄については、今回は全体の数だけを考えて増減させるため、 BoidType に該当するもの全体の情報にアクセスする必要があり、そのために EntityQuery の生成 -> 対象となる NativeArray<Entity> の取得という流れで処理しています。 このへんは、状況に合わせて公式サンプルの SpawnFromMonoBehaviour , SpawnFromEntity, SpawnAndRemove あたりを参考にするのがよいでしょう。 ▽Entities.ForEach によるジョブ実装例 まず、entity 自身の情報が主な場合、今回の例でいえば MoveSystem の実装は下記のとおり。 [UpdateAfter(typeof(BoidSystemGroup))] public class MoveSystem : SystemBase { protected override void OnUpdate() { // パラメータをローカル変数として置いておき、ラムダ式にキャプチャさせる float dt = Time.DeltaTime; float minSpeed = Bootstrap.Param.maxSpeed; float maxSpeed = Bootstrap.Param.maxSpeed; // ジョブの定義 Dependency = Entities. WithName("MoveJob"). WithAll<BoidType>(). WithBurst(). ForEach((ref Translation pos, ref Rotation rotate, ref Velocity vel, ref Acceleration accel) => { vel.Value += accel.Value * dt; var dir = math.normalize(vel.Value); var speed = math.length(vel.Value); vel.Value = math.clamp(speed, minSpeed, maxSpeed) * dir; pos.Value += vel.Value * dt; var rot = quaternion.LookRotationSafe(dir, new float3(0, 1, 0)); rotate.Value = rot; accel.Value = float3.zero; }).ScheduleParallel(Dependency); } } float や int など単純な struct は適当にOnUpdate() 関数のローカル変数においておけば、同じスコープで書くラムダ式でキャプチャしてくれるので簡単に使えます。 ラムダ式の引数は、C#の仕様かEntitiesの仕様かはわかりませんが、 値渡し(実質 Entity 型のみ)、ref 渡し、in 渡し の順番で並べる必要があります。また、Entity 型以外を値渡しすると、処理中で書き換える引数に ref を、書き換えない引数には in をつけるように警告されます。 Entities と ForEach() の間にある With** 関数でエンティティクエリに属性を追加できます。 主なものはReferenceによれば下表のとおり。 エンティティクエリ 効果 WithName(string) Jobの名前を指定。プロファイラやEntityDebuggerでこの名前が使われる WithBurst Burst Compiler による最適化を適用 WithAll<T1, T2, T3> 処理対象のEntityはすべてのComponentTypeを持つ必要がある WithAny<T1, T2, T3> 処理対象のEntityはいずれかのComponentTypeを持つ必要がある WithNone<T1, T2, T3> 処理対象のEntityはいずれのComponentTypeも含まない必要がある WithChangeFilter<T1, T2> 指定されたComponentが前回のSystem実行時に変更されたものだけを処理する WithSharedComponentFilter(ISharedComponentData) ISharedComponentDataが特定の値のEntityだけを処理する WithEntityQueryOptions(EntityQueryOptions) EntityQueryOptionsに合致するものだけを処理する WithStoreEntityQueryInField(EntityQuery) SystemBase.EntityQuery に ForEach実行時に作成された EntityQuery を保存する。 対象Entityの全体数など、EntityQueryのインターフェイスを使いたい場合に用いる 上表中の <T1, T2, T3> は <T> または <T1, T2> に型パラメータを省略できます。(最大数は表中のとおり) 次に、自身以外の Entity の情報も必要な処理の例として、 CohesionSystem の実装は下記のとおり。 [UpdateInGroup(typeof(BoidSystemGroup))] public class CohesionSystem : SystemBase { private struct CohesionDataContainer { [ReadOnly] public float alignmentWeight; [ReadOnly] public ComponentDataFromEntity<Translation> positionFromGrovalEntity; } protected override void OnUpdate() { var common_data = new CohesionDataContainer { alignmentWeight = Bootstrap.Param.alignmentWeight, positionFromGrovalEntity = GetComponentDataFromEntity<Translation>(true), }; Dependency = Entities. WithName("CohesionJob"). WithAll<BoidType>(). WithBurst(). ForEach( (ref Acceleration accel, in Translation pos, in DynamicBuffer<NeighborsEntityBuffer> neighbors) => { if (neighbors.Length == 0) return; float3 pos_avg = float3.zero; float3 pos0 = pos.Value; float3 acc = accel.Value; for(int i=0; i<neighbors.Length; i++) { pos_avg += common_data.positionFromGrovalEntity[neighbors[i].entity].Value; } pos_avg /= neighbors.Length; acc += (pos_avg - pos0) * common_data.alignmentWeight; accel = new Acceleration { Value = acc }; } ).ScheduleParallel(Dependency); } } ここで、 Entity 経由で他の Boid の Translation を参照するため、全EntityのTranslationへのアクセサを SystemBase.GetComponentDataFromEntity<Translation>(isReadOnly) で取得しています。このSystemでは Translation は書き換えないので isReadOnly = true です。この場合代入先は [ReadOnly] アトリビュートが付加されている必要があり、そのままでは関数内の一時変数には代入できません。 そのため、このデータの代入先として struct CohesionDataContainer の中に [ReadOnly] メンバを用意し、 CohesionDataContainer を一時変数として作ることでラムダ式にキャプチャさせることができます。 ▼IJobEntityBatch の例 (非推奨) IJobEntityBatch を使って CohesionSystem を書くと下記のようになります。 [UpdateInGroup(typeof(BoidSystemGroup))] public class CohesionSystem : SystemBase { // チャンク検索のため EntityQuery が必須 (IJobEntityBatch.Schedule()の引数) private EntityQuery query; protected override void OnCreate() { base.OnCreate(); query = GetEntityQuery(new EntityQueryDesc { All = new[] { ComponentType.ReadOnly<BoidType>(), ComponentType.ReadOnly<Translation>(), ComponentType.ReadOnly<NeighborsEntityBuffer>(), ComponentType.ReadWrite<Acceleration>() } }); } [BurstCompile] public struct CohesionJob : IJobEntityBatch { [ReadOnly] public float alignmentWeight; [ReadOnly] public ComponentDataFromEntity<Translation> positionFromGrovalEntity; // アクセサのハンドルを受け取るためのメンバ。 var で受け取れないのでひたすら面倒 [ReadOnly] public ComponentTypeHandle<Translation> translationHandle; [ReadOnly] public BufferTypeHandle<NeighborsEntityBuffer> neighborsBufferHandle; public ComponentTypeHandle<Acceleration> accelHandle; public void Execute(ArchetypeChunk batchInChunk, int batchIndex) { var pos_array = batchInChunk.GetNativeArray(translationHandle); var neighbors_list = batchInChunk.GetBufferAccessor(neighborsBufferHandle); var acc_array = batchInChunk.GetNativeArray(accelHandle); // チャンク内のイテレーションは自分で書く。 // 1段ネストが増える分手間だしバグ混入の危険も増える for(int i=0; i<batchInChunk.Count; i++) { var neighbors = neighbors_list[i]; if (neighbors.Length == 0) continue; float3 pos_avg = float3.zero; float3 pos0 = pos_array[i].Value; float3 acc = acc_array[i].Value; for (int j = 0; j < neighbors.Length; j++) { pos_avg += positionFromGrovalEntity[neighbors[j].entity].Value; } pos_avg /= neighbors.Length; acc += (pos_avg - pos0) * alignmentWeight; acc_array[i] = new Acceleration { Value = acc }; } // ComponentType のアクセサが NativeArray<> を返すので Dispose する必要がある pos_array.Dispose(); acc_array.Dispose(); } } protected override void OnUpdate() { var param = Bootstrap.Param; var job = new CohesionJob { alignmentWeight = param.alignmentWeight, positionFromGrovalEntity = GetComponentDataFromEntity<Translation>(true), // 必要な ComponentType, BufferType の Handle をいちいち渡す必要がある translationHandle = GetComponentTypeHandle<Translation>(), neighborsBufferHandle = GetBufferTypeHandle<NeighborsEntityBuffer>(), accelHandle = GetComponentTypeHandle<Acceleration>() }; // ここで渡す EntityQuery も自分で組み立てる必要がある Dependency = job.ScheduleParallel(query, 1, Dependency); } } 上記は Entities.ForEach の例と同じ処理ですが、書かなければならないコードの量と複雑さが圧倒的です。 そのため、公式でも 「どうしてもIJobEntityBatchを使う必要がない限りEntities.ForEachを使おう」 と言っています。 参考記事 Original implementation: Unity で Boids シミュレーションを作成して Entity Component System (ECS) を学んでみた Qiita: ECSの簡単な実装と変更点について 既存のUnityプロジェクトをUniversalRenderPipelineに移行する -サードインパクト修復- Official: Entities Hybrid Renderer EntityComponentSystemSamples
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityでゲーム開発

今回は「 Carrom 」というボードゲームを題材に Unity と Blender を利用して開発しました。 Carrom とは ・ボードゲーム ・ビリヤードによく似ている ・自分のコイン(ストライカー)を指で弾いて中心のコインにぶつけて  四隅の穴(ポケット)に入れる ルールの設定 ・2人で行う ・交代制 ・青チームは白いコインを、緑チームは茶色のコインを全て落とし  最後に赤いコインを落とすと勝利 ・真ん中の赤いコインは得点が3点 他のコインは1点 その他にも細々としたルールを設定していますが 大きな流れは上記のようになっています。 Background と Object を配置 初めに Background (背景)や Object (コイン、ストライカー)を配置しました。 配置しただけなので動きはない状態です。 スコア機能の作成 スコアTextをゲーム画面に表示させ、 四隅の黒い穴にコインが当たったらスコアText に点数を追加するスクリプトを作成しました。 中央の赤いコインは得点が3点なので Tag( red )で判別させます。 不具合が発生しないか確認し無事実装完了! ...ですが、 開発途中にスコア機能が勝敗に関係ない事に気付きました。 設計書を作成している途中で気づくべきミスだったと反省しています。 せっかく作ったのでスコアは表示させたままにしました。 ストライカーの動作処理 今回はクリックした場所にストライカーを飛ばすよう設定しました。 Striker.cs if (Input.GetMouseButtonDown(0)) { Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); Vector3 shotForward = mouseWorldPos - transform.position; shotForward = Vector3.Scale(shotForward, new Vector3(1, 0, 1)) shotForward = shotForward.normalized; rigidbody.AddForce(shotForward * strikerSpeed); } 実装後Unity 内 Main Cameraの Projection を Orthographic に切り替えます。 Perspective ... 遠近法を使った描写 Orthographic ... 平行投射を使った描写 Perspectiveを利用するとゲーム画面に奥行きができます。今回の開発したゲームは遠近法を利用しないものだったので Orthographic を利用しました。 ターン制の実装 対戦相手用のObject(ストライカー)を配置後、ターン制を実装させるための スクリプトを作成しました。 ターン制は真偽値を利用しました。 下記はターン制を簡単に再現したコードです。 GameManager.cs public classGameManager : MonoBehaviour { public GameObject Sphere; public static bool PlayerTurn; void Start() { Sphere.SetActive (true); PlayerTurn = true; } void Update() { if (PlayerTurn == true) { Sphere.SetActive (false); PlayerTurn = false; } } } 相手のスコア機能実装 対戦相手のスコアText を作成し、コインにTagを付けます。 コインの色を Tag で区別し(白は white 、茶色は brown ) 穴に入ったコインの Tag が whiteだった場合は青に1点 brownだった場合は緑に1点 としました。 勝利TextとRETRYボタンの実装 if 自分のコインが全て落ちた && 赤コインが落ちた 場合 勝利Textを表示 としました。 緑用のTextも用意し、全て落ちたコインのTagによって表示させるTextを分岐させています。 上手く機能しますがかっこいいフォントが見つからず一番修正したい部分です。 RETRYボタンを勝利Textと同じタイミングで表示させます。 ボタン押下後、スコアを0にし、コインとストライカーをスタート時と同じ位置に配置させました。 Blenderでコイン作成 配置 Blenderでコインを作成しUnityにエクスポートしました。 配置前(左)と配置後(右)です。コインが変わるだけでゲームの印象がガラリと変わります。 まとめ 個人でのゲーム開発は初めてでしたがとても面白かったです。 色々な気付きや発見、失敗がありました。 技術不足はもちろんですが、設計書に関しても反省がありました。 開発途中に設計書のミスに気付き修正した部分が多く、設計書の荒が課題だと感じました。 今回の学びをこれからのものづくりに活かしていきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】柔軟な入力に対応したタイピングゲームの作り方(改良編)【C#】

はじめに 前回【Unity】柔軟な入力に対応したタイピングゲームの作り方(導入編)【C#】という記事の続きです。 現在のタイピングゲームの要となる「柔軟な入力(「つ」→「tsu」、「ふ」→「fu」)」に対応させます。 WindowsとMacで異なる入力方法 タイピングの入力方法については、以下のURLが参考になります。 Windows:https://www.cc.saga-u.ac.jp/system/CenterSystem/ime_romaji.htm Mac:https://support.apple.com/ja-jp/guide/japanese-input-method/jpim10277/6.2.1/mac/10.15 よくよく確認すると、WindowsとMacでは入力方法が異なることがわかります。(例:Windowsでは「か」を「ca」と入力できるが、Macではできない) なので、WindowsとMacを区別する必要があります。 ちなみにこの機能は省略しても構いません。 TypingManager.cs public class TypingManager : MonoBehaviour { private bool _isWindows; //追加する private bool _isMac; //追加する void Start() { // 以下を追加する if(SystemInfo.operatingSystem.Contains("Windows")) { _isWindows = true; } if(SystemInfo.operatingSystem.Contains("Mac")) { _isMac = true; } // ここまで } } 柔軟な入力に対応させるアルゴリズム「前後比較法」 現在の日本語入力タイピングゲームにおいて、柔軟な入力に対応させるアルゴリズムはいくつか存在します。 今回は「前後比較法(私が勝手に名付けた方法です)」を使います。 「前後比較法」は、今入力すべき文字とその文字の前後を比較することによって「どのひらがなを入力するのか」を判断して、入力してもOKな文字を抽出するアルゴリズムです。 例えば「うちわ(utiwa)」を考えましょう。 まず最初の入力文字が「u」なので、入力するひらがなは「う」であることが判明します。「う」の別入力が「wu」であるので「w」を入力しても構わないことがわかります。 当然ですが、別入力を行いますとローマ字を改良する必要があります。今回の例で「w」を入力するとローマ字表記は「wutiwa」に変化します。 次の入力文字も「u」ですが、前の文字が「w」なので「う」の入力途中であることが判明します。よって今回は「w」を入力することができません。 そして「u」の入力後、入力文字が「t」になります。この入力文字の前が母音で、後の文字が「i」なので「ち」を入力することが判明します。同様に「ち」の別入力は「chi」なので「c」を入力してもOKとなります。 もちろん「c」を入力した後は「wuchiwa」に変形する必要があります。 こんな感じでほかの文字に対応させることができます。 InputKey() を大幅に改造しよう! 上記のアルゴリズムを用いて、InputKey() を大幅に改造します。 TypingManager.cs int InputKey(char inputChar) { char prevChar3 = _romanIndex >= 3 ? _roman[_romanIndex - 3] : '\0'; char prevChar2 = _romanIndex >= 2 ? _roman[_romanIndex - 2] : '\0'; char prevChar = _romanIndex >= 1 ? _roman[_romanIndex - 1] : '\0'; char currentChar = _roman[_romanIndex]; char nextChar = _roman[_romanIndex + 1]; char nextChar2 = nextChar == '@' ? '@' : _roman[_romanIndex + 2]; if (inputChar == '\0') { return 0; } if (inputChar == currentChar) { return 1; } //「い」の柔軟な入力(Windowsのみ) if (_isWindows && inputChar == 'y' && currentChar == 'i' && (prevChar == '\0' || prevChar == 'a' || prevChar == 'i' || prevChar == 'u' || prevChar == 'e' || prevChar == 'o')) { _roman.Insert(_romanIndex, 'y'); return 1; } if (_isWindows && inputChar == 'y' && currentChar == 'i' && prevChar == 'n' && prevChar2 == 'n' && prevChar3 != 'n') { _roman.Insert(_romanIndex, 'y'); return 1; } if (_isWindows && inputChar == 'y' && currentChar == 'i' && prevChar == 'n' && prevChar2 == 'x') { _roman.Insert(_romanIndex, 'y'); return 1; } //「う」の柔軟な入力(「whu」はWindowsのみ) if (inputChar == 'w' && currentChar == 'u' && (prevChar == '\0' || prevChar == 'a' || prevChar == 'i' || prevChar == 'u' || prevChar == 'e' || prevChar == 'o')) { _roman.Insert(_romanIndex, 'w'); return 1; } if (inputChar == 'w' && currentChar == 'u' && prevChar == 'n' && prevChar2 == 'n' && prevChar3 != 'n') { _roman.Insert(_romanIndex, 'w'); return 1; } if (inputChar == 'w' && currentChar == 'u' && prevChar == 'n' && prevChar2 == 'x') { _roman.Insert(_romanIndex, 'w'); return 1; } if (_isWindows && inputChar == 'h' && prevChar2 != 't' && prevChar2 != 'd' && prevChar == 'w' && currentChar == 'u') { _roman.Insert(_romanIndex, 'h'); return 1; } //「か」「く」「こ」の柔軟な入力(Windowsのみ) if (_isWindows && inputChar == 'c' && prevChar != 'k' && currentChar == 'k' && (nextChar == 'a' || nextChar == 'u' || nextChar == 'o')) { _roman[_romanIndex] = 'c'; return 1; } //「く」の柔軟な入力(Windowsのみ) if (_isWindows && inputChar == 'q' && prevChar != 'k' && currentChar == 'k' && nextChar == 'u') { _roman[_romanIndex] = 'q'; return 1; } //「し」の柔軟な入力 if (inputChar == 'h' && prevChar == 's' && currentChar == 'i') { _roman.Insert(_romanIndex, 'h'); return 1; } //「じ」の柔軟な入力 if (inputChar == 'j' && currentChar == 'z' && nextChar == 'i') { _roman[_romanIndex] = 'j'; return 1; } //「しゃ」「しゅ」「しぇ」「しょ」の柔軟な入力 if (inputChar == 'h' && prevChar == 's' && currentChar == 'y') { _roman[_romanIndex] = 'h'; return 1; } //「じゃ」「じゅ」「じぇ」「じょ」の柔軟な入力 if (inputChar == 'z' && prevChar != 'j' && currentChar == 'j' && (nextChar == 'a' || nextChar == 'u' || nextChar == 'e' || nextChar == 'o')) { _roman[_romanIndex] = 'z'; _roman.Insert(_romanIndex + 1, 'y'); return 1; } if (inputChar == 'y' && prevChar == 'j' && (currentChar == 'a' || currentChar == 'u' || currentChar == 'e' || currentChar == 'o')) { _roman.Insert(_romanIndex, 'y'); return 1; } //「し」「せ」の柔軟な入力(Windowsのみ) if (_isWindows && inputChar == 'c' && prevChar != 's' && currentChar == 's' && (nextChar == 'i' || nextChar == 'e')) { _roman[_romanIndex] = 'c'; return 1; } //「ち」の柔軟な入力 if (inputChar == 'c' && prevChar != 't' && currentChar == 't' && nextChar == 'i') { _roman[_romanIndex] = 'c'; _roman.Insert(_romanIndex + 1, 'h'); return 1; } //「ちゃ」「ちゅ」「ちぇ」「ちょ」の柔軟な入力 if (inputChar == 'c' && prevChar != 't' && currentChar == 't' && nextChar == 'y') { _roman[_romanIndex] = 'c'; return 1; } //「cya」=>「cha」 if (inputChar == 'h' && prevChar == 'c' && currentChar == 'y') { _roman[_romanIndex] = 'h'; return 1; } //「つ」の柔軟な入力 if (inputChar == 's' && prevChar == 't' && currentChar == 'u') { _roman.Insert(_romanIndex, 's'); return 1; } //「つぁ」「つぃ」「つぇ」「つぉ」の柔軟な入力 if (inputChar == 'u' && prevChar == 't' && currentChar == 's' && (nextChar == 'a' || nextChar == 'i' || nextChar == 'e' || nextChar == 'o')) { _roman[_romanIndex] = 'u'; _roman.Insert(_romanIndex + 1, 'x'); return 1; } if (inputChar == 'u' && prevChar2 == 't' && prevChar == 's' && (currentChar == 'a' || currentChar == 'i' || currentChar == 'e' || currentChar == 'o')) { _roman.Insert(_romanIndex, 'u'); _roman.Insert(_romanIndex + 1, 'x'); return 1; } //「てぃ」の柔軟な入力 if (inputChar == 'e' && prevChar == 't' && currentChar == 'h' && nextChar == 'i') { _roman[_romanIndex] = 'e'; _roman.Insert(_romanIndex + 1, 'x'); return 1; } //「でぃ」の柔軟な入力 if (inputChar == 'e' && prevChar == 'd' && currentChar == 'h' && nextChar == 'i') { _roman[_romanIndex] = 'e'; _roman.Insert(_romanIndex + 1, 'x'); return 1; } //「でゅ」の柔軟な入力 if (inputChar == 'e' && prevChar == 'd' && currentChar == 'h' && nextChar == 'u') { _roman[_romanIndex] = 'e'; _roman.Insert(_romanIndex + 1, 'x'); _roman.Insert(_romanIndex + 2, 'y'); return 1; } //「とぅ」の柔軟な入力 if (inputChar == 'o' && prevChar == 't' && currentChar == 'w' && nextChar == 'u') { _roman[_romanIndex] = 'o'; _roman.Insert(_romanIndex + 1, 'x'); return 1; } //「どぅ」の柔軟な入力 if (inputChar == 'o' && prevChar == 'd' && currentChar == 'w' && nextChar == 'u') { _roman[_romanIndex] = 'o'; _roman.Insert(_romanIndex + 1, 'x'); return 1; } //「ふ」の柔軟な入力 if (inputChar == 'f' && currentChar == 'h' && nextChar == 'u') { _roman[_romanIndex] = 'f'; return 1; } //「ふぁ」「ふぃ」「ふぇ」「ふぉ」の柔軟な入力(一部Macのみ) if (inputChar == 'w' && prevChar == 'f' && (currentChar == 'a' || currentChar == 'i' || currentChar == 'e' || currentChar == 'o')) { _roman.Insert(_romanIndex, 'w'); return 1; } if (inputChar == 'y' && prevChar == 'f' && (currentChar == 'i' || currentChar == 'e')) { _roman.Insert(_romanIndex, 'y'); return 1; } if (inputChar == 'h' && prevChar != 'f' && currentChar == 'f' && (nextChar == 'a' || nextChar == 'i' || nextChar == 'e' || nextChar == 'o')) { if (_isMac) { _roman[_romanIndex] = 'h'; _roman.Insert(_romanIndex + 1, 'w'); } else { _roman[_romanIndex] = 'h'; _roman.Insert(_romanIndex + 1, 'u'); _roman.Insert(_romanIndex + 2, 'x'); } return 1; } if (inputChar == 'u' && prevChar == 'f' && (currentChar == 'a' || currentChar == 'i' || currentChar == 'e' || currentChar == 'o')) { _roman.Insert(_romanIndex, 'u'); _roman.Insert(_romanIndex + 1, 'x'); return 1; } if (_isMac && inputChar == 'u' && prevChar == 'h' && currentChar == 'w' && (nextChar == 'a' || nextChar == 'i' || nextChar == 'e' || nextChar == 'o')) { _roman[_romanIndex] = 'u'; _roman.Insert(_romanIndex + 1, 'x'); return 1; } //「ん」の柔軟な入力(「n'」には未対応) if (inputChar == 'n' && prevChar2 != 'n' && prevChar == 'n' && currentChar != 'a' && currentChar != 'i' && currentChar != 'u' && currentChar != 'e' && currentChar != 'o' && currentChar != 'y') { _roman.Insert(_romanIndex, 'n'); return 1; } if (inputChar == 'x' && prevChar != 'n' && currentChar == 'n' && nextChar != 'a' && nextChar != 'i' && nextChar != 'u' && nextChar != 'e' && nextChar != 'o' && nextChar != 'y') { if (nextChar == 'n') { _roman[_romanIndex] = 'x'; } else { _roman.Insert(_romanIndex, 'x'); } return 1; } //「きゃ」「にゃ」などを分解する if (inputChar == 'i' && currentChar == 'y' && (prevChar == 'k' || prevChar == 's' || prevChar == 't' || prevChar == 'n' || prevChar == 'h' || prevChar == 'm' || prevChar == 'r' || prevChar == 'g' || prevChar == 'z' || prevChar == 'd' || prevChar == 'b' || prevChar == 'p') && (nextChar == 'a' || nextChar == 'u' || nextChar == 'e' || nextChar == 'o')) { if (nextChar == 'e') { _roman[_romanIndex] = 'i'; _roman.Insert(_romanIndex + 1, 'x'); } else { _roman.Insert(_romanIndex, 'i'); _roman.Insert(_romanIndex + 1, 'x'); } return 1; } //「しゃ」「ちゃ」などを分解する if (inputChar == 'i' && (currentChar == 'a' || currentChar == 'u' || currentChar == 'e' || currentChar == 'o') && (prevChar2 == 's' || prevChar2 == 'c') && prevChar == 'h') { if (nextChar == 'e') { _roman.Insert(_romanIndex, 'i'); _roman.Insert(_romanIndex + 1, 'x'); } else { _roman.Insert(_romanIndex, 'i'); _roman.Insert(_romanIndex + 1, 'x'); _roman.Insert(_romanIndex + 2, 'y'); } return 1; } //「しゃ」を「c」で分解する(Windows限定) if (_isWindows && inputChar == 'c' && currentChar == 's' && prevChar != 's' && nextChar == 'y' && (nextChar2 == 'a' || nextChar2 == 'u' || nextChar2 == 'e' || nextChar2 == 'o')) { if (nextChar2 == 'e') { _roman[_romanIndex] = 'c'; _roman[_romanIndex + 1] = 'i'; _roman.Insert(_romanIndex + 1, 'x'); } else { _roman[_romanIndex] = 'c'; _roman.Insert(_romanIndex + 1, 'i'); _roman.Insert(_romanIndex + 2, 'x'); } return 1; } //「っ」の柔軟な入力 if ((inputChar == 'x' || inputChar == 'l') && (currentChar == 'k' && nextChar == 'k' || currentChar == 's' && nextChar == 's' || currentChar == 't' && nextChar == 't' || currentChar == 'g' && nextChar == 'g' || currentChar == 'z' && nextChar == 'z' || currentChar == 'j' && nextChar == 'j' || currentChar == 'd' && nextChar == 'd' || currentChar == 'b' && nextChar == 'b' || currentChar == 'p' && nextChar == 'p')) { _roman[_romanIndex] = inputChar; _roman.Insert(_romanIndex + 1, 't'); _roman.Insert(_romanIndex + 2, 'u'); return 1; } //「っか」「っく」「っこ」の柔軟な入力(Windows限定) if (_isWindows && inputChar == 'c' && currentChar == 'k' && nextChar == 'k' && (nextChar2 == 'a' || nextChar2 == 'u' || nextChar2 == 'o')) { _roman[_romanIndex] = 'c'; _roman[_romanIndex + 1] = 'c'; return 1; } //「っく」の柔軟な入力(Windows限定) if (_isWindows && inputChar == 'q' && currentChar == 'k' && nextChar == 'k' && nextChar2 == 'u') { _roman[_romanIndex] = 'q'; _roman[_romanIndex + 1] = 'q'; return 1; } //「っし」「っせ」の柔軟な入力(Windows限定) if (_isWindows && inputChar == 'c' && currentChar == 's' && nextChar == 's' && (nextChar2 == 'i' || nextChar2 == 'e')) { _roman[_romanIndex] = 'c'; _roman[_romanIndex + 1] = 'c'; return 1; } //「っちゃ」「っちゅ」「っちぇ」「っちょ」の柔軟な入力 if (inputChar == 'c' && currentChar == 't' && nextChar == 't' && nextChar2 == 'y') { _roman[_romanIndex] = 'c'; _roman[_romanIndex + 1] = 'c'; return 1; } //「っち」の柔軟な入力 if (inputChar == 'c' && currentChar == 't' && nextChar == 't' && nextChar2 == 'i') { _roman[_romanIndex] = 'c'; _roman[_romanIndex + 1] = 'c'; _roman.Insert(_romanIndex + 2, 'h'); return 1; } //「l」と「x」の完全互換性 if (inputChar == 'x' && currentChar == 'l') { _roman[_romanIndex] = 'x'; return 1; } if (inputChar == 'l' && currentChar == 'x') { _roman[_romanIndex] = 'l'; return 1; } return 2; } こうすることによって、「し」を「shi」、んを「xn」などと入力することができます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】柔軟な入力に対応したタイピングゲームの作り方(導入編)【C#】

はじめに 最近はPC離れが加速し、モバイルゲームが主流となった今、タイピングゲームは減少傾向です。 しかしながら普段からキーボードを叩いてコーディングを行っている人々は、タイピングゲームを作りたいと思ったことはないでしょうか? また、タイピングゲームの作成に挫折してしまう人々も少なくないと思います。 なぜなら、タイピングゲームは作りにくいと思うからです。 というのも、今のタイピングゲームは、「し」を「shi」、「ち」を「chi」など、柔軟な入力に対応しています。 これらがなくてもタイピングゲームとしては成立しますが、それでは非常に操作性の悪いタイピングゲームとなってしまい、今時公開できるようなものではありません。 また「柔軟な入力に対応していないタイピングゲームなんて公開できないよ!」と思っている開発者も多いかもしれません。 なので今回はUnityで柔軟な入力に対応したタイピングゲームを作る方法を記述します。 今回はUnityの記事ですが、Unity以外の言語やフレームワークでも参考になれば光栄です。 対象読者は、ある程度Unityが触れて、TextMeshProなどが使えることを想定しています。 とりあえずUnityを起動してプロジェクトを作成しよう とにかく、まずUnityのプロジェクトが存在しないことには、何も始まりません。 なので普段通り、Unityのプロジェクトを作成します。(2Dでも3DでもURPでもお好きに) 今回はTextMeshProを使いますので、TextMeshProをインポートします。 そして、タイピングゲームに必ずといっていいほど存在する「日本語表示用のテキスト」と「ローマ字表示用のテキスト」のTextMeshProオブジェクトを作成します。 また、日本語表示用のテキストには、日本語表示に対応したTextMeshPro用のフォントアセットを用意します。 次に「TypingManager.cs」を作成します。 そして、Hierarchy上に「TypingManager」という空のGameObjectを作成して、そこに先ほど作成した「TypingManager.cs」をInspector上でアタッチします。 ここからは延々と「TypingManager.cs」にコードを書くだけです。 最終的には以下のようになります。 完成したコード TypingManager.cs using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; [Serializable] public class Question { public string japanese; public string roman; } public class TypingManager : MonoBehaviour { [SerializeField] private Question[] questions; [SerializeField] private TextMeshProUGUI textJapanese; // ここに日本語表示のTextMeshProをアタッチする。 [SerializeField] private TextMeshProUGUI textRoman; // ここにローマ字表示のTextMeshProをアタッチする。 private readonly List<char> _roman = new List<char>(); private int _romanIndex; private void Start() { InitializeQuestion(); } private void OnGUI() { if (Event.current.type == EventType.KeyDown) { switch (InputKey(GetCharFromKeyCode(Event.current.keyCode))) { case 1: // 正解タイプ時 _romanIndex++; if (_roman[_romanIndex] == '@') // 「@」がタイピングの終わりの判定となる。 { InitializeQuestion(); } else { textRoman.text = GenerateTextRoman(); } break; case 2: // ミスタイプ時 break; } } } void InitializeQuestion() { Question question = questions[UnityEngine.Random.Range(0, questions.Length)]; _roman.Clear(); _romanIndex = 0; char[] characters = question.roman.ToCharArray(); foreach (char character in characters) { _roman.Add(character); } _roman.Add('@'); textJapanese.text = question.japanese; textRoman.text = GenerateTextRoman(); } string GenerateTextRoman() { string text = "<style=typed>"; for (int i = 0; i < _roman.Count; i++) { if (_roman[i] == '@') { break; } if (i == _romanIndex) { text += "</style><style=untyped>"; } text += _roman[i]; } text += "</style>"; return text; } int InputKey(char inputChar) { if (inputChar == '\0') { return 0; } if (inputChar == _roman[_romanIndex]) { return 1; } return 2; } char GetCharFromKeyCode(KeyCode keyCode) { switch (keyCode) { case KeyCode.A: return 'a'; case KeyCode.B: return 'b'; case KeyCode.C: return 'c'; case KeyCode.D: return 'd'; case KeyCode.E: return 'e'; case KeyCode.F: return 'f'; case KeyCode.G: return 'g'; case KeyCode.H: return 'h'; case KeyCode.I: return 'i'; case KeyCode.J: return 'j'; case KeyCode.K: return 'k'; case KeyCode.L: return 'l'; case KeyCode.M: return 'm'; case KeyCode.N: return 'n'; case KeyCode.O: return 'o'; case KeyCode.P: return 'p'; case KeyCode.Q: return 'q'; case KeyCode.R: return 'r'; case KeyCode.S: return 's'; case KeyCode.T: return 't'; case KeyCode.U: return 'u'; case KeyCode.V: return 'v'; case KeyCode.W: return 'w'; case KeyCode.X: return 'x'; case KeyCode.Y: return 'y'; case KeyCode.Z: return 'z'; case KeyCode.Alpha0: return '0'; case KeyCode.Alpha1: return '1'; case KeyCode.Alpha2: return '2'; case KeyCode.Alpha3: return '3'; case KeyCode.Alpha4: return '4'; case KeyCode.Alpha5: return '5'; case KeyCode.Alpha6: return '6'; case KeyCode.Alpha7: return '7'; case KeyCode.Alpha8: return '8'; case KeyCode.Alpha9: return '9'; case KeyCode.Minus: return '-'; case KeyCode.Caret: return '^'; case KeyCode.Backslash: return '\\'; case KeyCode.At: return '@'; case KeyCode.LeftBracket: return '['; case KeyCode.Semicolon: return ';'; case KeyCode.Colon: return ':'; case KeyCode.RightBracket: return ']'; case KeyCode.Comma: return ','; case KeyCode.Period: return '_'; case KeyCode.Slash: return '/'; case KeyCode.Underscore: return '_'; case KeyCode.Backspace: return '\b'; case KeyCode.Return: return '\r'; case KeyCode.Space: return ' '; default: //上記以外のキーが押された場合は「null文字」を返す。 return '\0'; } } } これだけだとわかりにくいと思うので、コードを解説します。 コードの解説 何かしらの入力イベントが生じた時に呼ばれるイベント関数 OnGUI() Unityではスクリプトの生成時に最初から存在するUpdate()というのが存在しますが、もっと便利なイベント関数OnGUI()が存在します。 これは何かしらの入力イベントが生じた時に呼び出され、以下のように書くことによってキーボードの入力が発生した時に処理を走らせることができます。 private void OnGUI() { if (Event.current.type == EventType.KeyDown) { // キーが入力された時に処理を実行する } } OnGUI()関数にEvent.current.type == EventType.KeyDownという条件式を書けば、キーの入力時のみtrueとなって、処理が実行されます。 これをタイピングゲームとして機能させるには、以下の通りです。 private void OnGUI() { if (Event.current.type == EventType.KeyDown) { switch (InputKey(GetCharFromKeyCode(Event.current.keyCode))) { case 1: // 正解タイプ時 _romanIndex++; if (_roman[_romanIndex] == '@') // 「@」がタイピングの終わりの判定となる。 { InitializeQuestion(); } else { textRoman.text = GenerateTextRoman(); } break; case 2: // ミスタイプ時 break; } } } ここから InputKey() や GetCharFromKeyCode() InitializeQuestion() GenerateRomanText() ならびに _roman[] _romanIndex について解説していきます。 KeyCodeをcharに変換する関数 GetCharFromKeyCode() キーが入力され OnGUI() が実行されると Event.current.keyCode に入力されたキーコードが格納されます。型は KeyCode です。 この型はタイピングゲームのアルゴリズム実装には不向きですので、KeyCode を char に変換する関数 GetCharFromKeyCode() を実装しました。 以下のようになりました。今回はShift入力は省略しています。 char GetCharFromKeyCode(KeyCode keyCode) { switch (keyCode) { case KeyCode.A: return 'a'; case KeyCode.B: return 'b'; case KeyCode.C: return 'c'; case KeyCode.D: return 'd'; case KeyCode.E: return 'e'; case KeyCode.F: return 'f'; case KeyCode.G: return 'g'; case KeyCode.H: return 'h'; case KeyCode.I: return 'i'; case KeyCode.J: return 'j'; case KeyCode.K: return 'k'; case KeyCode.L: return 'l'; case KeyCode.M: return 'm'; case KeyCode.N: return 'n'; case KeyCode.O: return 'o'; case KeyCode.P: return 'p'; case KeyCode.Q: return 'q'; case KeyCode.R: return 'r'; case KeyCode.S: return 's'; case KeyCode.T: return 't'; case KeyCode.U: return 'u'; case KeyCode.V: return 'v'; case KeyCode.W: return 'w'; case KeyCode.X: return 'x'; case KeyCode.Y: return 'y'; case KeyCode.Z: return 'z'; case KeyCode.Alpha0: return '0'; case KeyCode.Alpha1: return '1'; case KeyCode.Alpha2: return '2'; case KeyCode.Alpha3: return '3'; case KeyCode.Alpha4: return '4'; case KeyCode.Alpha5: return '5'; case KeyCode.Alpha6: return '6'; case KeyCode.Alpha7: return '7'; case KeyCode.Alpha8: return '8'; case KeyCode.Alpha9: return '9'; case KeyCode.Minus: return '-'; case KeyCode.Caret: return '^'; case KeyCode.Backslash: return '\\'; case KeyCode.At: return '@'; case KeyCode.LeftBracket: return '['; case KeyCode.Semicolon: return ';'; case KeyCode.Colon: return ':'; case KeyCode.RightBracket: return ']'; case KeyCode.Comma: return ','; case KeyCode.Period: return '_'; case KeyCode.Slash: return '/'; case KeyCode.Underscore: return '_'; case KeyCode.Backspace: return '\b'; case KeyCode.Return: return '\r'; case KeyCode.Space: return ' '; default: //上記以外のキーが押された場合は「null文字」を返す。 return '\0'; } } (うん、これはひどい・・・でもこれが私の最適解です(笑)) こうすることによって、KeyCode を char に変換しています。 また、Functionキーなどが入力された場合でも OnGUI() が実行され Event.current.keyCode に格納され、上記の関数が実行されますが、その場合はnull文字 \0 を返しています。 タイピングの正誤判定を行う関数 InputKey() タイピングゲームには、キーの入力が正しいか否かを判断する機能が必要になります。 なので、それを行うための関数 InputKey() を実装します。 int InputKey(char inputChar) { if (inputChar == '\0') { return 0; } if (inputChar == _roman[_romanIndex]) { return 1; } return 2; } キーの入力によって OnGUI() 関数が呼ばれ、GetCharFromKeyCode() の戻り値 char が InputKey() の引数となって、int を返します。 正しい入力であれば 1 を返し、ミスタイプであれば 2 を返します。また入力に対応していないキーが入力された場合は 0 を返しています。 後の記事で上記の関数を編集し、柔軟な入力に対応させます。 タイピングの状態を格納するインスタンス変数 _roman _romanIndex タイピングゲームを作るからには、当然タイピング用の入力文の入力状態をコントロールする変数が必要になります。 using System.Collections.Generic; public class TypingManager : MonoBehaviour { private readonly List<char> _roman = new List<char>(); private int _romanIndex; } _roman はタイピングの入力文字の処理に用いられる List<char> のインスタンス変数で、頻繁に Add() Clear() が用いられますので、今回は List<T> となっております。 Unityではスクリプトの生成時に作成されますが、using System.Collections.Generic; を忘れないようにしてください。 そして、_romanIndex は _roman の参照に用いられるだけの int 型のインスタンス変数です。 問題を初期化する関数 InitializeQuestion() と、問題文を格納するクラス配列 questions どんなタイピングゲームにも、問題を初期化する必要がありますので、それを行うための関数 InitializeQuestion() を実装します。 void InitializeQuestion() { Question question = questions[UnityEngine.Random.Range(0, questions.Length)]; _roman.Clear(); _romanIndex = 0; char[] characters = question.roman.ToCharArray(); foreach (char character in characters) { _roman.Add(character); } _roman.Add('@'); textJapanese.text = question.japanese; textRoman.text = GenerateTextRoman(); } Clear() によって _roman の中身を空にし、_romanIndex を 0 に設定し、その後、クラス配列 questions からランダムに一つ取り出して格納されたクラス question の roman プロパティ( string 型)を ToCharArray() によって char[] に変換し、foreach を用いることによって、_roman に次から次へと Add() で文字を追加します。 そして、_roman の最後に @ を Add() します。この @ が「タイピングの終わり」であることを示します。 タイピングゲームには、タイピング用の文字列のリストが必要になります。 よって、Questionクラスを作成して、[Serializable] [SerializeField] でインスペクタ上から文字列を編集できるようにします。 using System; using TMPro; using UnityEngine; [Serializable] public class Question { public string japanese; public string roman; } public class TypingManager : MonoBehaviour { [SerializeField] private Question[] questions; [SerializeField] private TextMeshProUGUI textJapanese; // ここに日本語表示のTextMeshProをアタッチする。 [SerializeField] private TextMeshProUGUI textRoman; // ここにローマ字表示のTextMeshProをアタッチする。 } そしてインスペクタ上で文字列とローマ字表記を入力します。 (必ず日本式(「し」→「si」、「ち」→「ti」)で入力して、「ん」の後に「な行」や「あ行」が来る場合は「nnna」及び「nna」などと入力してください。後ほどの記事で柔軟な入力方法に響きます。  また、諸事情でjapaneseがTitleになっています。) また、_textJapanese _textRoman は、画面に表示するためのTextMeshProオブジェクトを格納するインスタンス変数です。 インスペクタ上でアタッチを行います。 表示用のテキスト情報を生成する関数 GenerateRomanText() タイピングゲームでは当たり前のように、入力前の文字と入力後の文字で色が異なりますので、それを実装するための関数 GenerateRomanText() を実装します。 string GenerateTextRoman() { string text = "<style=typed>"; for (int i = 0; i < _roman.Count; i++) { if (_roman[i] == '@') { break; } if (i == _romanIndex) { text += "</style><style=untyped>"; } text += _roman[i]; } text += "</style>"; return text; } TextMeshProにはタグ機能が搭載されており、特定の部分のみスタイルを変更する <style> タグを使用します。 ただし、このままでは画面上に <style> が表示されてしまいます。なのでUnityエディタ上で「Project Settings」→「TextMesh Pro」の「Settings」→「Default Style Sheet」の「Default Style Sheet (TMP_StyleSheet)」をダブルクリックして、インスペクタ上で以下のようにタグとタグ情報を追加します。 こうすることによって、<style>は表示されなくなり、タイピングの入力前と入力後の文字の色が変わります。 さいごに コードの解説は以上です。 長々としたコード及び記事をお読みいただき、誠にありがとうございます。 タイピングゲームとして動作しましたでしょうか? しかし、これでは表示されているローマ字以外のタイピングができないため、非常に操作性の悪いタイピングゲームとなっているはずです。 次の記事で柔軟な入力に対応させます。 【Unity】柔軟な入力に対応したタイピングゲームの作り方(改良編)【C#】
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C#におけるXMLファイルの処理でツボったNamespaceについての個人的なメモ

RSSフィードなんかではよくXMLファイルが使われていますよね? 個人的にRSSフィードからXMLファイルを取得し、C#で操作しようしたのですがツボにハマりました。 この記事はそのとき色々悩んで解決に至ったメモです。 例えば、下記XMLファイルで、そのままタグを選択しようとしても上手くいきません。 XMLファイル クリックで展開 <rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel rdf:about="http://alfalfalfa.com/"> <title>アルファルファモザイク</title> <description>2ちゃんねるのスレッドを紹介するブログです。</description> <link>http://alfalfalfa.com/</link> <dc:language>ja</dc:language> <items> <rdf:Seq> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302951.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302917.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302939.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302935.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302938.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302933.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302921.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302934.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302920.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302929.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302913.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302911.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302910.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302896.html"/> <rdf:li rdf:resource="http://alfalfalfa.com/articles/302894.html"/> </rdf:Seq> </items> </channel> <item rdf:about="http://alfalfalfa.com/articles/302951.html"> <title>【pickup】【悲報】新卒のサイバーエージェント社員がプチ炎上してしまう</title> <link>http://alfalfalfa.com/articles/302951.html</link> <description>この記事はアルファルファモザイクで話題になったネタを羅列して紹介している記事です。【悲報】新卒のサイバーエージェント社員がプチ炎上してしまう1:2020/04/21(火) 21:08:47ID:dE7X6kgQa.net続きを読む関連記事document.write('' + '');</description> <dc:date>2021-04-15T11:20:00+09:00</dc:date> <dc:subject>ピックアップニュース</dc:subject> <content:encoded><![CDATA[ <div class="pickup_main"><br><h2>この記事はアルファルファモザイクで話題になったネタを羅列して紹介している記事です。</h2><br><div class="daily_popular_title"><a href="http://alfalfalfa.com/articles/281913.html?utm_source=alfalfa&utm_medium=">【悲報】新卒のサイバーエージェント社員がプチ炎上してしまう</a></div><br><ul><!-- anchovy --><div id="res_1" class="res_block" style="border-bottom:none;"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2020/04/21(火) 21:08:47</span><span class="res_id">ID:dE7X6kgQa.net</span></span></div><div class="res_body"></div></div></ul><br><br><br><div class="clearfix"></div><br><footer class="article_bodyfooter" style="margin: 15px 0 50px 0"><br><div class="readmore"><a href="http://alfalfalfa.com/articles/281913.html?utm_source=alfalfa&utm_medium=">続きを読む</a></div><br></footer><br><hr class="daily_popular_separator" /><br><br></div><br><br><br><div id="related-title">関連記事</div><br><ul class="automatic-related" id="mainmore"><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><br></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302917.html"> <title>【悲報】フワちゃん、とんでもないクズエピソード暴露。</title> <link>http://alfalfalfa.com/articles/302917.html</link> <description>春日は、一緒に帰宅中にフワちゃんから直接、聞いた話を披露。フワちゃんが歯医者でバイトをしていた頃、院長からいろいろと教わるためにデニーズに行った。だが、話を聞いてるあいだ、「ちょっと、行ってきやす」と何回もドリンクを取りに行ったため、院長を怒らせ、「その場でクビになった」という。https://news.yahoo.co.jp/articles/4211bcc5ccdcead76c1f490e91</description> <dc:date>2021-04-15T11:01:00+09:00</dc:date> <dc:subject>ニュース</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/4299001893/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/3/2/323c223132e762a69cccc40ea615d62a742970531618388717.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="デニーズ ドリンクバー 春日 クビ あいだに関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="news_quote">春日は、一緒に帰宅中にフワちゃんから直接、聞いた話を披露。フワちゃんが歯医者でバイトをしていた頃、院長からいろいろと教わるためにデニーズに行った。<br>だが、話を聞いてるあいだ、「ちょっと、行ってきやす」と何回もドリンクを取りに行ったため、院長を怒らせ、「その場でクビになった」という。<br><br><a href="https://news.yahoo.co.jp/articles/4211bcc5ccdcead76c1f490e91e8cd14d8f11341" target="_blank" rel="nofollow">https://news.yahoo.co.jp/articles/4211bcc5ccdcead76c1f490e91e8cd14d8f11341</a><br>※上記リンクより、一部抜粋。続きはソースで<br></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302939.html"> <title>【画像】小栗有以ちゃんがバラエティ番組でヨガに挑戦中に放送事故。</title> <link>http://alfalfalfa.com/articles/302939.html</link> <description>1:2021/04/12(月) 18:42:44.83ID: &amp;nbsp; https://imgur.com/TOo2qNf.jpg &amp;nbsp; https://imgur.com/6yzAq4F.jpg &amp;nbsp; https://imgur.com/yZq5fPT.jpg &amp;nbsp; https://imgur.com/z37DUob.jpgdocument.write('' + ''</description> <dc:date>2021-04-15T09:55:00+09:00</dc:date> <dc:subject>エンタメ</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B08XKBQDXY/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/2/f/2f298e9c4bd7a5870d68787455482caa3552a65a1618406279.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="程 体勢 胸元 谷間 ガチ絶壁に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/12(月) 18:42:44.83</span><span class="res_id">ID:</span></span></div><br><div class="res_body"><blockquote class="imgur-embed-pub" lang="ja" data-id="TOo2qNf"><a href="//imgur.com/TOo2qNf"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/TOo2qNf.jpg" target="_blank" rel="nofollow">https://imgur.com/TOo2qNf.jpg</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="6yzAq4F"><a href="//imgur.com/6yzAq4F"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/6yzAq4F.jpg" target="_blank" rel="nofollow">https://imgur.com/6yzAq4F.jpg</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="yZq5fPT"><a href="//imgur.com/yZq5fPT"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/yZq5fPT.jpg" target="_blank" rel="nofollow">https://imgur.com/yZq5fPT.jpg</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="z37DUob"><a href="//imgur.com/z37DUob"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/z37DUob.jpg" target="_blank" rel="nofollow">https://imgur.com/z37DUob.jpg</a></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302935.html"> <title>【速報】あの芸能事務所マネージャー、やっぱりやっていたと判明。</title> <link>http://alfalfalfa.com/articles/302935.html</link> <description>テレビ局関係者は語る。以前、付き合いのある大手芸能事務所のマネージャーから誘われ食事に行くと、今では人気タレントになったXを連れてきていて、3人で食事をした。当時、Xはまだ無名でしたが、店を出るとマネージャーは『このあとは、Xを●さんの好きにしていいですよ』と言って、私とXを置いて先に帰ってしまった。大手事務所に弱みを握られても、いいことは何もないので、すぐにXにはタクシー代として1万円を渡して、</description> <dc:date>2021-04-15T09:01:00+09:00</dc:date> <dc:subject>ニュース</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B08BZ41N52/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/b/3/b319f7e691434d52d784c4d1784ff8589ab15f381618403701.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="タクシ 弱み 無名 マネージャー 大手事務所マネに関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="news_quote">テレビ局関係者は語る。<br>以前、付き合いのある大手芸能事務所のマネージャーから誘われ食事に行くと、今では人気タレントになったXを連れてきていて、3人で食事をした。<br>当時、Xはまだ無名でしたが、店を出るとマネージャーは『このあとは、Xを●さんの好きにしていいですよ』と言って、私とXを置いて先に帰ってしまった。<br>大手事務所に弱みを握られても、いいことは何もないので、すぐにXにはタクシー代として1万円を渡して、一人でタクシーに乗せて帰しました。<br><br><a href="https://biz-journal.jp/2021/04/post_219829.html" target="_blank" rel="nofollow">https://biz-journal.jp/2021/04/post_219829.html</a><br>※上記リンクより、一部抜粋。続きはソースで<br></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302938.html"> <title>【速報】小室圭、決定的証拠を突き付けられ無事死亡。</title> <link>http://alfalfalfa.com/articles/302938.html</link> <description>4月8日、小室さんは代理人を通じて、28枚にわたる説明文書を公表した。文書では、佳代さんの元婚約者・X氏の「返してもらうつもりはなかった」との発言が、計23回、言及されている。 根拠となっているのは2012年9月に小室さん母子とX氏が面会した時の音声記録。圭さんが金銭にまつわるやり取りになった際に、とっさに録音したものだという。説明文書にはその音声記録からの抜粋として、「返してもらうつもりはなかっ</description> <dc:date>2021-04-15T07:45:00+09:00</dc:date> <dc:subject>ニュース</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B0757HJYFF/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/7/6/76b68b4703d65a5f7c35f93505705ee2ee5f69481618405411.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="文言 月日 代理人 氏 ピンチに関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="news_quote">4月8日、小室さんは代理人を通じて、28枚にわたる説明文書を公表した。<br>文書では、佳代さんの元婚約者・X氏の「返してもらうつもりはなかった」との発言が、計23回、言及されている。<br><br> 根拠となっているのは2012年9月に小室さん母子とX氏が面会した時の音声記録。<br>圭さんが金銭にまつわるやり取りになった際に、とっさに録音したものだという。<br>説明文書にはその音声記録からの抜粋として、「返してもらうつもりはなかったんだ」とのX氏の文言が記されている。<br><br><a href="https://news.yahoo.co.jp/articles/618641f8525d2a2011b2d8fdff0221b2d0bd383b?page=1" target="_blank" rel="nofollow">https://news.yahoo.co.jp/articles/618641f8525d2a2011b2d8fdff0221b2d0bd383b?page=1</a><br>※上記リンクより、一部抜粋。続きはソースで<br><br><iframe width="640" height="360" src="https://www.youtube.com/embed/QeR65Mz2DAE" frameborder="0" allowfullscreen></iframe><a href="https://www.youtube.com/watch?v=QeR65Mz2DAE" target="_blank" rel="nofollow">https://www.youtube.com/watch?v=QeR65Mz2DAE</a><br></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302933.html"> <title>【pickup】【画像】ひき逃げ女さんの御尊顔がこちらwwwwwwwwwwwwwwwwwwwwwwwww</title> <link>http://alfalfalfa.com/articles/302933.html</link> <description>この記事はアルファルファモザイクで話題になったネタを羅列して紹介している記事です。【画像】ひき逃げ女さんの御尊顔がこちらwwwwwwwwwwwwwwwwwwwwwwwww1:2021/04/13(火) 13:40:31.44ID:3z4nogCL0.net続きを読む関連記事document.write('' + '');</description> <dc:date>2021-04-15T06:10:00+09:00</dc:date> <dc:subject>ピックアップニュース</dc:subject> <content:encoded><![CDATA[ <div class="pickup_main"><br><h2>この記事はアルファルファモザイクで話題になったネタを羅列して紹介している記事です。</h2><br><div class="daily_popular_title"><a href="http://alfalfalfa.com/articles/302862.html?utm_source=alfalfa&utm_medium=">【画像】ひき逃げ女さんの御尊顔がこちらwwwwwwwwwwwwwwwwwwwwwwwww</a></div><br><ul><!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B0918BLQVJ/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/3/6/36541c6d4b39c2e68195836fa7534c3effde6ce01618298991.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="ノーメイク 信用せんぞ 湾岸ミッドナイト 過失致死 執行猶予に関連した画像-01"></a></div><div id="res_1" class="res_block" style="border-bottom:none;"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/13(火) 13:40:31.44</span><span class="res_id">ID:3z4nogCL0.net</span></span></div><div class="res_body"></div></div></ul><br><br><br><div class="clearfix"></div><br><footer class="article_bodyfooter" style="margin: 15px 0 50px 0"><br><div class="readmore"><a href="http://alfalfalfa.com/articles/302862.html?utm_source=alfalfa&utm_medium=">続きを読む</a></div><br></footer><br><hr class="daily_popular_separator" /><br><br></div><br><br><br><div id="related-title">関連記事</div><br><ul class="automatic-related" id="mainmore"><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><br></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302921.html"> <title>【閲覧注意】ベッキー、無修正。</title> <link>http://alfalfalfa.com/articles/302921.html</link> <description>1:2021/04/13(火) 23:01:35.402ID:XRh093Mvd.net &amp;nbsp; http://imgur.com/2TdOrdX.jpgdocument.write('' + '');関連記事document.write('' + '');</description> <dc:date>2021-04-15T06:01:00+09:00</dc:date> <dc:subject>エンタメ</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B00FUBM92Q/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/6/2/622a47fe4a3ee43152c750b76662862bd0f83d3c1618390522.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="ベッキー ディズニー映画 無修正 新人類 画像に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/13(火) 23:01:35.402</span><span class="res_id">ID:XRh093Mvd.net</span></span></div><br><div class="res_body"><blockquote class="imgur-embed-pub" lang="ja" data-id="2TdOrdX"><a href="//imgur.com/2TdOrdX"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="http://imgur.com/2TdOrdX.jpg" target="_blank" rel="nofollow">http://imgur.com/2TdOrdX.jpg</a></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302934.html"> <title>【pickup】【速報】渋谷で地獄絵図。</title> <link>http://alfalfalfa.com/articles/302934.html</link> <description>この記事はアルファルファモザイクで話題になったネタを羅列して紹介している記事です。【速報】渋谷で地獄絵図。1:2021/04/14(水) 13:33:12.84ID:+gzLRHmIa.net続きを読む関連記事document.write('' + '');</description> <dc:date>2021-04-15T05:10:00+09:00</dc:date> <dc:subject>ピックアップニュース</dc:subject> <content:encoded><![CDATA[ <div class="pickup_main"><br><h2>この記事はアルファルファモザイクで話題になったネタを羅列して紹介している記事です。</h2><br><div class="daily_popular_title"><a href="http://alfalfalfa.com/articles/302914.html?utm_source=alfalfa&utm_medium=">【速報】渋谷で地獄絵図。</a></div><br><ul><!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/4865063099/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/4/8/48a7b83e802b1b7344337b000d3fee9d63fe329e1618385949.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="ドバト ヒヨドリ 渡り鳥 月日 冒頭に関連した画像-01"></a></div><div id="res_1" class="res_block" style="border-bottom:none;"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/14(水) 13:33:12.84</span><span class="res_id">ID:+gzLRHmIa.net</span></span></div><div class="res_body"></div></div></ul><br><br><br><div class="clearfix"></div><br><footer class="article_bodyfooter" style="margin: 15px 0 50px 0"><br><div class="readmore"><a href="http://alfalfalfa.com/articles/302914.html?utm_source=alfalfa&utm_medium=">続きを読む</a></div><br></footer><br><hr class="daily_popular_separator" /><br><br></div><br><br><br><div id="related-title">関連記事</div><br><ul class="automatic-related" id="mainmore"><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><br></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302920.html"> <title>【画像】幼稚園児ホスト、琉ちゃろ君の現在wwwwwwwwww</title> <link>http://alfalfalfa.com/articles/302920.html</link> <description>1:2021/04/13(火) 22:24:56.971ID:qIoPS/Sv0.net相変わらずままんの玩具の模様 &amp;nbsp; https://imgur.com/9dxgYff.jpg &amp;nbsp; https://imgur.com/YtSDwVK.jpg &amp;nbsp; https://imgur.com/4UGiekk.jpg &amp;nbsp; https://imgur.com/9lyr9</description> <dc:date>2021-04-15T05:05:00+09:00</dc:date> <dc:subject>エンタメ</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B08WLTNNR2/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/e/7/e787c6f51c1fa259581a545efc86af9eae673b871618390224.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="カラコン 反面教師 ホスト 喧嘩 玩具に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/13(火) 22:24:56.971</span><span class="res_id">ID:qIoPS/Sv0.net</span></span></div><br><div class="res_body">相変わらずままんの玩具の模様<br><blockquote class="imgur-embed-pub" lang="ja" data-id="9dxgYff"><a href="//imgur.com/9dxgYff"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/9dxgYff.jpg" target="_blank" rel="nofollow">https://imgur.com/9dxgYff.jpg</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="YtSDwVK"><a href="//imgur.com/YtSDwVK"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/YtSDwVK.jpg" target="_blank" rel="nofollow">https://imgur.com/YtSDwVK.jpg</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="4UGiekk"><a href="//imgur.com/4UGiekk"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/4UGiekk.jpg" target="_blank" rel="nofollow">https://imgur.com/4UGiekk.jpg</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="9lyr9Nj"><a href="//imgur.com/9lyr9Nj"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/9lyr9Nj.jpg" target="_blank" rel="nofollow">https://imgur.com/9lyr9Nj.jpg</a></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302929.html"> <title>【画像】令和の女子プロレスラー、あまりにもヤバすぎるwwwwwww</title> <link>http://alfalfalfa.com/articles/302929.html</link> <description>1:2021/04/13(火) 23:14:13.949ID:ccJ/+n90d.net &amp;nbsp; http://imgur.com/cz58bk5.jpg &amp;nbsp; https://imgur.com/DtBRqNw.jpgdocument.write('' + '');関連記事document.write('' + '');</description> <dc:date>2021-04-15T05:01:00+09:00</dc:date> <dc:subject>スポーツ</dc:subject> <content:encoded><![CDATA[ <!-- anchovy3 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B00CS9O59S/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/b/8/b85647dd8d48e34d17444bef1cf31a312ad9aa391618395987.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="グラドル 全員神崎忍 令和 ダンプ松本系 ヤバすぎるwwwwwwwに関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/13(火) 23:14:13.949</span><span class="res_id">ID:ccJ/+n90d.net</span></span></div><br><div class="res_body"><blockquote class="imgur-embed-pub" lang="ja" data-id="cz58bk5"><a href="//imgur.com/cz58bk5"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="http://imgur.com/cz58bk5.jpg" target="_blank" rel="nofollow">http://imgur.com/cz58bk5.jpg</a><br><br> <blockquote class="imgur-embed-pub" lang="ja" data-id="DtBRqNw"><a href="//imgur.com/DtBRqNw"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/DtBRqNw.jpg" target="_blank" rel="nofollow">https://imgur.com/DtBRqNw.jpg</a></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302913.html"> <title>【悲報】マジック:ザ・ギャザリングさん、その辺の萌え萌えカードゲームになってしまう。</title> <link>http://alfalfalfa.com/articles/302913.html</link> <description>1:2021/04/14(水) 08:56:11.73ID:iAUvyrhwa.net最新の広告がこれらしい &amp;nbsp; https://imgur.com/buFCSDD.jpgdocument.write('' + '');関連記事document.write('' + '');</description> <dc:date>2021-04-15T04:00:00+09:00</dc:date> <dc:subject>ゲーム,趣味一般</dc:subject> <content:encoded><![CDATA[ <!-- anchovy1 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/4894252902/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/4/f/4f58608c1199dea88f0f85e16d7fcc518266a0271618385209.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="鋤 チャンドラおばさん エルドレイン ヴァンガード シャドウバースに関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/14(水) 08:56:11.73</span><span class="res_id">ID:iAUvyrhwa.net</span></span></div><br><div class="res_body">最新の広告がこれらしい<br><br> <blockquote class="imgur-embed-pub" lang="ja" data-id="buFCSDD"><a href="//imgur.com/buFCSDD"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/buFCSDD.jpg" target="_blank" rel="nofollow">https://imgur.com/buFCSDD.jpg</a></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302911.html"> <title>【悲報】漫画の天才キャラ、扱いが難しすぎる… </title> <link>http://alfalfalfa.com/articles/302911.html</link> <description>1:2021/04/14(水) 01:33:57.14ID:N2kjDL1gd.netどうやっても作者以上の知能を描くことはできない模様document.write('' + '');関連記事document.write('' + '');</description> <dc:date>2021-04-15T03:00:00+09:00</dc:date> <dc:subject>アニメ・マンガ</dc:subject> <content:encoded><![CDATA[ <!-- anchovy1 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B01BG88F06/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/1/b/1bf836a2af2e14dc678fec71e1492fb4acb10be81618383614.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="暗算 箔 しゃー コンクール 知能に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/14(水) 01:33:57.14</span><span class="res_id">ID:N2kjDL1gd.net</span></span></div><br><div class="res_body">どうやっても作者以上の知能を描くことはできない模様</div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302910.html"> <title>日本の未来→中国と組んで経済豊かで幸せな暮らしをするか 米国の犬で今まで通り苦しい生活をするか </title> <link>http://alfalfalfa.com/articles/302910.html</link> <description>1:2021/04/13(火) 12:07:09.38ID:WS5WKiYq0.net米国か中国か?日本経済界に踏み絵、対応誤れば「死」https://www.asahi.com/articles/ASP3X36T6P3WULFA00K.htmldocument.write('' + '');関連記事document.write('' + '');</description> <dc:date>2021-04-15T02:00:00+09:00</dc:date> <dc:subject>政治</dc:subject> <content:encoded><![CDATA[ <!-- anchovy1 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B0056WFQ1A/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/5/3/534bd14a9c6e9f3791a45893e5636f85a42286f01618381117.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="踏み絵 東シナ海 ブリンケン国務長 尖閣 全文に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/13(火) 12:07:09.38</span><span class="res_id">ID:WS5WKiYq0.net</span></span></div><br><div class="res_body">米国か中国か?日本経済界に踏み絵、対応誤れば「死」<br><a href="https://www.asahi.com/articles/ASP3X36T6P3WULFA00K.html" target="_blank" rel="nofollow">https://www.asahi.com/articles/ASP3X36T6P3WULFA00K.html</a></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302896.html"> <title>中国人、ついに気付く 「もしかして日中韓が団結したらアメリカ抜いちゃうんじゃね?」 </title> <link>http://alfalfalfa.com/articles/302896.html</link> <description>1:2021/04/13(火) 15:00:54.29ID:j9xsOYTZ0.net米中関係は対立を深めているが、米国への対抗策として日韓と手を組むことを考える中国人もいるようだ。 中国の動画サイト・西瓜視頻はこのほど、「日中韓が団結したら米国を超えられるか」と題する動画を配信した。 動画はあくまで可能性を論じているだけだが、大真面目に国内総生産(GDP)、科学技術、軍事力の観点から「日中韓連合</description> <dc:date>2021-04-15T01:00:00+09:00</dc:date> <dc:subject>政治</dc:subject> <content:encoded><![CDATA[ <!-- anchovy1 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B00BZ13QY0/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/a/d/ad57359addf40200cca026f0d21eb84011d814051618372545.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="コロナ 西瓜視頻 GDP 対立 観点に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="res_info"><span class="res_num">1</span>:<span class="res_name"></span><span class="res_matome"><span class="res_date">2021/04/13(火) 15:00:54.29</span><span class="res_id">ID:j9xsOYTZ0.net</span></span></div><br><div class="res_body">米中関係は対立を深めているが、米国への対抗策として日韓と手を組むことを考える中国人もいるようだ。<br><br> 中国の動画サイト・西瓜視頻はこのほど、「日中韓が団結したら米国を超えられるか」と題する動画を配信した。<br><br> 動画はあくまで可能性を論じているだけだが、大真面目に国内総生産(GDP)、科学技術、軍事力の観点から「日中韓連合と米国の実力」を比較している。<br><br> まずは「GDP」について、米国も3カ国の合計も21兆ドル前後でほぼ同じだと分析した。しかし、日中韓が心を一つにして発展すればさらに実力を発揮できるので、米国を軽々と超えられると主張している。<br><br> では、「科学技術」はどうだろうか。動画では、米国は宇宙開発と情報技術、核開発では強いものの、製造業などの分野では「日本が圧倒的に強い」としている。日本だけでも米国を超えているので、ここに中国と韓国の実力が加われば楽に米国を引き離せるとした。<br><br> 最後の「軍事力」については、単純に比較すると日中韓は3カ国を合わせても米国ほどの軍事力はないという。ただ、日韓は米国の「弟分」として軍事面の発展を抑えられているため、もし、自由になって中国と協力すれば米国を超えるのも夢ではないと主張している。<br><br> 動画は結論として、日中韓3カ国が団結して協力すれば米国を超えられると自信たっぷりに伝えている。<br><br> <a href="http://news.searchina.net/id/1698319?page=1" target="_blank" rel="nofollow">http://news.searchina.net/id/1698319?page=1</a><br><br>もう日本が生き残るにはこの道しかないだろう</div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> <item rdf:about="http://alfalfalfa.com/articles/302894.html"> <title>「素足のJKを取り戻したい」「JKの制服は素足がいい」と複数の学校に電話していた男、無事逮捕。</title> <link>http://alfalfalfa.com/articles/302894.html</link> <description>福岡県宗像市の学校に「素足が見えない生徒を見つけたら殺す」という主旨の脅迫電話を掛け、学校の業務を妨害したとして48歳の男が逮捕されました。  警察によりますと、白川堅太郎容疑者は先月、宗像市内の学校に「くるぶしまでの靴下をはいている生徒を見つけたら殺すぞ。分かったな」などと電話を掛け、学校の職員らに敷地内の警戒をさせるなど業務を妨害した疑いが持たれています。白川容疑者は「女子高校生の制服は素足が</description> <dc:date>2021-04-15T00:00:00+09:00</dc:date> <dc:subject>ニュース</dc:subject> <content:encoded><![CDATA[ <!-- anchovy1 --><div class="catch_amz"><a href="https://www.amazon.co.jp/gp/product/B07DHN4P7W/?tag=alfalfathum-22&linkCode=osi&th=1&psc=1" target="_blank"><img src="https://articleimage.nicoblomaga.jp/image/279/2021/2/8/283fbb25063649104684a67f61afc25d6df54bd01618370546.jpg" border="0" hspace="5" vspace="5" class="body_topimg_amz" alt="くるぶし 主旨 素足 白川堅太郎容疑者 靴下に関連した画像-01"></a></div><div id="res_1" class="res_block"><div class="news_quote">福岡県宗像市の学校に「素足が見えない生徒を見つけたら殺す」という主旨の脅迫電話を掛け、学校の業務を妨害したとして48歳の男が逮捕されました。<br><br>  警察によりますと、白川堅太郎容疑者は先月、宗像市内の学校に「くるぶしまでの靴下をはいている生徒を見つけたら殺すぞ。分かったな」などと電話を掛け、<br>学校の職員らに敷地内の警戒をさせるなど業務を妨害した疑いが持たれています。白川容疑者は「女子高校生の制服は素足がいい」と1年ほど前から複数の学校に電話を掛けていて、<br>変わらないことに腹を立て今回の犯行に及んだと話しているということです。「素足の女子高校生を取り戻したかった」と容疑を認めています。<br><a href="http://news.tv-asahi.co.jp/sphone/news_society/articles/000101030.html" target="_blank" rel="nofollow">http://news.tv-asahi.co.jp/sphone/news_society/articles/000101030.html</a><br><blockquote class="imgur-embed-pub" lang="ja" data-id="oagQeDO"><a href="//imgur.com/oagQeDO"> &nbsp; </a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script><br><a href="https://imgur.com/oagQeDO.png" target="_blank" rel="nofollow">https://imgur.com/oagQeDO.png</a><br><br>※上記リンクより、一部抜粋。続きはソースで<br></div></div><br><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/bodyb.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script><div id="related-title">関連記事</div><ul class="automatic-related" id="mainmore"><script type="text/javascript">document.write('<scr' + 'ipt type="text/javascript" src="http://blogmaterial.nicoblomaga.jp/material/279/js/kanren2.js?' + Math.floor((new Date)/1000) + '">' + '</scr' + 'ipt>');</script></ul><br><br> ]]></content:encoded> </item> </rdf:RDF> 次のコードは、読み込んだ上記のXMLファイルから"title"タグの値を抽出し、コンソールで表示することを目的に書いたものです。 Program.cs namespace ConsoleApp1{ class Program{ static void Main(string[] args){ //XMLファイルの取得 var testfile = XDocument.Load("http://alfalfalfa.com/index.rdf"); //ルート要素を選択 var rss = testfile.Root.Elements(); foreach(var x in rss){ //"title"タグを選択 var title = x.Element("title"); if (title != null){ //"title"タグの値を表示 Console.WriteLine(title.Value); } } } } } 実行結果 console //何も表示されない 何も表示されなかった原因は、Namespaseの指定をしていなかいからです。(していだけに、ガハハ!) この問題はNameプロパティのNapaspaceの値を取得し、指定することで解決できます。 Program.cs namespace ConsoleApp1{ class Program{ static void Main(string[] args){ //XMLファイルの取得 var testfile = XDocument.Load("http://alfalfalfa.com/index.rdf"); //ルート要素を選択 var rss = testfile.Root.Elements(); foreach(var x in rss){ //Namespaseの値を取得(修正箇所) var ns = x.Name.Namespace; //ns + "title"タグを選択(修正箇所) var title = x.Element(ns + "title"); if (title != null){ //ns + "title"タグの値を表示 Console.WriteLine(title.Value); } } } } } 実行結果 console アルファルファモザイク 【pickup】【悲報】新卒のサイバーエージェント社員がプチ炎上してしまう 【悲報】フワちゃん、とんでもないクズエピソード暴露。 【画像】小栗有以ちゃんがバラエティ番組でヨガに挑戦中に放送事故。 【速報】あの芸能事務所マネージャー、やっぱりやっていたと判明。 【速報】小室圭、決定的証拠を突き付けられ無事死亡。 【pickup】【画像】ひき逃げ女さんの御尊顔がこちらwwwwwwwwwwwwwwwwwwwwwwwww 【閲覧注意】ベッキー、無修正。 【pickup】【速報】渋谷で地獄絵図。 【画像】幼稚園児ホスト、琉ちゃろ君の現在wwwwwwwwww 【画像】令和の女子プロレスラー、あまりにもヤバすぎるwwwwwww 【悲報】マジック:ザ・ギャザリングさん、その辺の萌え萌えカードゲームになってしまう。 【悲報】漫画の天才キャラ、扱いが難しすぎる…  日本の未来→中国と組んで経済豊かで幸せな暮らしをするか 米国の犬で今まで通り苦しい生活をするか  中国人、ついに気付く 「もしかして日中韓が団結したらアメリカ抜いちゃうんじゃね?」  「素足のJKを取り戻したい」「JKの制服は素足がいい」と複数の学校に電話していた男、無事逮捕。 上手くいきました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

unityを用いずにwindowsアプリケーション(C#)とros(ubuntu)で通信を行う

初めに siemens社のros-sharpによりrosbridgeを用いてros melodicと通信を行います。 ros-sharpを動かすpcとrosを動かすpcの二台が同じlan環境内にあることを前提とします。 ros-sharpは、visual studio 2019 community を用いて開発を行います。 rosは、ubuntu 18.04 & melodicです。 環境構築 ROS ros bridgeを参考に行います。 sudo apt-get install ros-melodic-rosbridge-server rosのバージョンは環境に合わせて読み替えてください。 また、私の環境ではポート9090を開放しないと上手く動きませんでした。 Windows リポジトリを適当なところにzipでダウンロードしてください。 ビルド windows ros-sharp-master→Libraries内のRosSharp.slnをvisualstudioで開きます。 main関数はRosSocketConsoleExample.csにあり、 RosSocketConsoleExample.cs static readonly string uri = "ws://192.168.***.***:9090"; には、rosを動かしているpcのipアドレスを入力します RosBridgeClientTestをスタートアッププロジェクトにしてビルドを行います。 実行 ros側を先に実行します。 3つターミナルを立ち上げて実行します。 ROS 1 export ROS_IP=192.168.***.*** export ROS_MASTER_URI=http://192.168.***.***:11311 roslaunch rosbridge_server rosbridge_websocket.launch address:=192.168.***.*** 2 rostopic echo /publication_test 3 rostopic pub /subscription_test std_msgs/String "subscription test message data" windows ros-sharp-master\Libraries\RosBridgeClientTest\binにある、実行ファイルを実行します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む