martes, 7 de febrero de 2017

Unityゲーム

こちらではUnityを使ったゲームをご紹介します。

Speeed! (スピーード!)

開発中


Running Dungeon(ランニングダンジョン)

開発中




ツール:Unity、Visual Studio

言語: C#

プラットフォーム: Android

こちらは横スクロールRPGランゲーム。走る、ジャンプ、スライディング、の3つの基本操作でプレイヤーは永遠とダンジョンを進んでいきスコアを競い合うゲームです。アイテムなどをショップで買い、装備することでどんどん前に進めることができます。
キャラクターもダンジョンも複数あり、どのアイテムがどのキャラクターに、どのダンジョンに活用できるのかなどをプレイヤーに考えさせるところがポイントです。

私はプログラム、と絵の両方担当しております。またプログラムの方はGitHubにアップロードされておりませんので、こちらで一部を紹介させていただきます。





コウモリの回転スクリプト
using UnityEngine;
using System.Collections;

public class BatScript : MonoBehaviour 
{
public GameObject parent;

    private bool m_counterClockWise = true;

// 円の半径
private float r;
private float x;
private float y;
// 角度
private float alfa;

private Vector2 basePoint;

void calcBat()
{
Vector2 offset;
offset.x = parent.transform.position.x + 0.5f;//transform.parent.transform.position.x;
offset.y = basePoint.y;//transform.parent.transform.position.y;
x = Mathf.Cos (alfa) * r;
y = Mathf.Sin (alfa) * r;
Vector3 newPos = new Vector3 (offset.x + x, offset.y + y);
transform.position = newPos;
}

// Use this for initialization
void Start () 
{
        var random = Random.Range(0, 2);

        if(random == 0)
        {
            m_counterClockWise = true;
        }
        else
        {
            m_counterClockWise = false;
        }
        

alfa = 0.0f;
r = 1.45f;
basePoint = new Vector2 (transform.position.x, transform.position.y);

Vector2 offset;
offset.x = basePoint.x;
offset.y = basePoint.y;//transform.parent.transform.position.y;
x = Mathf.Cos (alfa) * r;
y = Mathf.Sin (alfa) * r;
Vector3 newPos = new Vector3 (offset.x + x, offset.y + y);
transform.position = newPos;
}

// Update is called once per frame
void Update () 
{
        if (m_counterClockWise)
            alfa += 2.0f * Time.deltaTime;
        else
            alfa -= 2.0f * Time.deltaTime;

        calcBat ();
}
}

モンスター基本行動スクリプト

using UnityEngine;
using System.Collections;

//Lizard script has a simple attacking behaviour
public class LizardScript : MonoBehaviour {

    [SerializeField]
    private int m_maxHp = 30;
    private int m_hp;

    private bool m_inCombat = false;
    private bool m_attacking = false;

    [SerializeField]
    private float m_waitingTime = 1.5f;
    private float m_timeCounter = 0.0f;

    private float m_impulseTime = 0.6f;
    private float m_reverseTime = 0.8f;

    private float m_resetTime = 1.5f;

    private Vector3 m_originalPos;
    private Vector3 m_originalScale;

    private GameObject m_hpBar;
    private PlayerStates m_playerStates;
    private int m_rarity = 0;

    //of 100%
    private int m_dropRate = 50;

    // Use this for initialization
    void Start ()
    {
        m_originalPos = transform.position;
        m_hpBar = transform.FindChild("hpBar").gameObject;
        m_originalScale = m_hpBar.transform.localScale;
        m_hp = m_maxHp;

        var character = GameObject.Find("character");
        m_playerStates = character.GetComponent<PlayerStates>();
    }

    void DropChest()
    {
        m_playerStates.DropChest();
    }

    void UpdateHPBar()
    {
        var scale = m_hpBar.transform.localScale;
        //rule of three calculation
        //max hp ----- 100%
        //current hp ---- X?

        scale.x = ((float)(m_hp * m_originalScale.x) / (float)m_maxHp);
        m_hpBar.transform.localScale = scale;

        if(m_hp <= 0)
        {
            transform.tag = "Untagged";
            transform.name = "deadMonster";
            m_playerStates.SetCombat(false);
            var luck = m_playerStates.GetLuck() * 2;
            var dropped = Random.Range(0, 100);
            if(m_dropRate + luck >= dropped)
            {
                //drop chest
                DropChest();
            }
        }
    }

// Update is called once per frame
void Update ()
    {
   if(transform.tag == "InCombatMonster")
        {
            //receive dmg
            if(m_playerStates.GetAttack())
            {
                var dmg = m_playerStates.GetDamage();
                if(dmg > m_hp)
                {
                    m_hp -= m_hp;
                }
                else
                {
                    m_hp -= dmg;
                }

                UpdateHPBar();

                m_playerStates.SetAttack(false);
            }

            //Wait and start attacking
            if (!m_attacking)
            {
                m_timeCounter += Time.deltaTime;
                //time to attack
                if (m_timeCounter >= m_waitingTime)
                {
                    m_attacking = true;
                    m_timeCounter = 0.0f;
                    m_originalPos = transform.position;
                }
            }
            //hard coded attack animation
            else
            {
                m_timeCounter += Time.deltaTime;

                if (m_timeCounter <= m_impulseTime)
                {
                    var pos = transform.position;
                    pos.x = Mathf.MoveTowards(pos.x, (m_originalPos.x + 1.0f), 1.66f * Time.deltaTime);
                    transform.position = pos;
                }
                else
                {
                    if (m_timeCounter <= m_reverseTime)
                    {
                        var pos = transform.position;
                        pos.x = Mathf.MoveTowards(pos.x, (m_originalPos.x - 1.0f), 10.0f * Time.deltaTime);
                        transform.position = pos;
                    }
                    else
                    {
                        var pos = transform.position;
                        pos.x = Mathf.MoveTowards(pos.x, (m_originalPos.x), 5.33f * Time.deltaTime);
                        transform.position = pos;

                        if(m_timeCounter >= m_resetTime)
                        {
                            m_attacking = false;
                            m_timeCounter = 0.0f;
                        }
                    }
                }
            }
        }
}

}



jueves, 10 de noviembre de 2016

Elixirレンダリングエンジン

こちらでは個人で開発しているレンダリングエンジンをご紹介します。

Elixir Engine


Elixir EngineはDirectX 11を使ったレンダリングエンジンです。エンジンの技術や構造を学ぶためでもあるこのエンジンは、PC向けの3Dゲームを開発できる様に心掛けた個人で制作をしているものです。





言語:C++ (DirectX 11)

プラットフォーム:PC

GitHub

これまで実装できている技術やレンダリングテクニックがこちらです:

  • 物理ベースレンダリング
  • ディファードレンダリング
  • 多光源対応(ポイントライト、スポットライト)
  • NvidiaのFXAA(アンチエイリアス)
  • トーンマッピング
  • 自動露光(視覚の順応)
  • ブルーム




miércoles, 19 de octubre de 2016

domingo, 31 de marzo de 2013

Basic Direct3D11

Once the window is created with the Win32 API, we have to initialize Direct3D11 enrolling the D3D rendering system to the window and render the scene to the window.

Simple D3D11 application (MSDN)

For this we have to include "d3d11.h" and "d3dx11.h".

Initialization

To initialize D3D11 we have to create a D3D11 device.
To create a D3D11 device we need to create COMs (component object model). It is used by D3D11 to be language independent and backward compatible (D3D10 and 9). These objects aren't created and destroyed with the C++ "new" and "delete" keyword respectively. (To destroy it we have to use the "Realease" method for each COM). COM are prefixed with a capital i, 'I'. The COM for a 2d texture is called ID3D11Texture2D.

Specifically we have to create (COM):

1. Render Target ( ID3D11RenderTargetView ): For some pipeline stages we are going to use a texture. D3D requires that we create a resource view in the moment of initialization for the texture. For now, we are going to use only the ID3D11RenderTargetView resource view. Basically, this is the texture for the backbuffer. (Where we process the scene).

2. Swap Chain ( IDXGISwapChain ): It defines two buffers (or more). Front and Back buffers. The COM uses those buffers to avoid flickering in animation.

3. Context ( ID3D11DeviceContext ): It binds the resources to the graphics pipeline (see pipeline stages).

4. Device ( ID3D11Device ): It is used to allocate all the resources.


Basically to initialize direct3d we have to do the following steps:

1. Create device and context.
2. Describe the swap chain.
3. Create the swap chain.
4. Create a render target view to the swap chain's backbuffer,
5. Bind render target view to the output merge state of the rendering pipeline (see pipeline states)
6. Set viewport.


The viewport defines the place where you want to render with d3d inside the window. Usually we set the viewport with the same dimentions of the window, but in some cases we want to render in a smaller subrenctangle.

Rendering

Once we have initialized D3D11 we want to render something with D3D11.
For the moment we are going to just clear the backbuffer and present it to the window.


1. Clear Render Target View: We are going to clear all the backbuffer with a specific color using the "ClearRenderTargetView" method in the Context COM.
2. Present: We present the backbuffer using the "Present" method in the SwapChain COM.


Structure

The structure of the program is something like:
WinMain
{
    Initialization (window initialization and d3d initialization)

    main loop (while is running)
    {
        Input( is running ? )
        Render
    }
}


Note:
We haven't created a depth/stencil buffer because we don't need it for a basic D3D application.
But it is required once we begin 3d rendering.

Win32


Create a window: DirectX API doesn't have the functionality to make windows, that's the reason why we need to use an external GUI libreary to handle the window and additionally the user input. In this case we are going to use Win32 API, which is included in almost all windows platforms.

In your Visual C++  go to File -> New -> Project. And then select "Win32 Project". Give it a name, and click "Ok". Click on "Next" and check the "Empty" box.


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE prevInstance, PSTR pScmdline, int iCmdshow )
{
}

That is the main(){} for windows applications. Each argument from the WinMain is needed for running correctly.

Inside the WinMain we have important things to keep in mind:
1. hInstance (HINSTANCE): An instance for the application, needed for window creation. 
2. WndProc function: It handles the messages for the window (input)
3. wc (WNDCLASSEX): Is the class for the window. It has some settings to be defined. For example, application name, icon, cursor, and so on.
4. hWnd (HWND): It stores the window. The window is created with the function 
CreateWindowEx( arguments... ) 

The functions with Ex at the end are the new Win32 fuctions.
For example CreateWindow( arguments... ) is a depredicated window creation fuction. In modern cases we use CreateWindowEx( arguments... ).