40년전 비행기를 600억에 사온다고? 미쳤나?

F-15가 들어오기 전까지 우리 공군의 주력기였던 F-4E 팬텀.

 

1970년대에 생산되어 걸프전에 사용했던 기체인데

미군 정비병들이 저건 못고친다고 버리자 했던걸
헐값에 들여와(1$ 라는 얘기도..)
한국의 정비병들이 고쳐낸걸 보고 혀를 내둘렀다지…

근데 이게 아직도 날고 있다니…

근데 이번에 40년된 대잠초계기 바이킹을 도입한다면서?

이미지중앙

가끔 조종사들 얘기를 들을 기회가 있었는데

저 팬텀기도 노후되서 비행 나갈 때 마다 불안하다고 했었다.
가끔 내장된 컴퓨터가 구형이라 레이더도 가끔 안켜져서
정말 목숨걸고 타야된다고 했었는데

아무리 상태가 좋아도 40년이 지난걸 600억이나주고
왜 사온다는건지 모르겠다.

하여간 미스터리 코리아. ㅎ

어째 하는 일마다 투명하게 하는 일이 없냐…

터닝메카드 정리

터닝메카드정리.
– 애들 손바닥 만한 사이즈의 변신 로봇.
– 자동으로 변신을 한다는게 포인트.
– 자석이 붙어있는 카드로 자동차 상태의 장난감을 굴리면
– 자력으로 스위치를 당겨 로봇으로 변신함.

– 개당 16,800원이 정가.
– 그러나 워낙 인기가 많아 더 비싸게 팔기도 하고
– 장난감 가게에서 끼워파는 경우도 허다함.
– 5만원짜리 카봇과 터닝매카드 하나를 묶어서 파는 방법..

– 현재 16종이 출시되었고 차후 20여종이 더 나온다고 함.
– 그런데 각 모델마다 색상이 3종류가 있어서 48가지라고 봐야함.
– 각 메카니멀마다 고유속성이 3가지씩 존재하는데
– 이것과 카드의 속성에 따른 점수를 이용해
대결을 하기 때문에 속성이 굉장히 중요한 요소임.

– 그런데 이건 본체에 붙어있는 스티커를 떼어야 속성을 확인 할 수 있어서
구매전에는 알수가 없음. 즉, 랜덤이라는 얘기!
– 1개당 메카드가 3장씩 들어있는데 테두리가 반짝이는 레어카드도 존재함.
– 그리고 카드는 당연히 랜덤…

– 터닝메카드 만화를 보면 서로 카드 세장씩을 내고 대결을 펼쳐서
이기는쪽이 그로기 상태가 된 상대의 메카니멀을 가져갈 수 있는데
– 요새 애들이 이걸 현실에서 따라함. -_-
심지어 만화 끝에 대전 방법을 매화 설명해줌.(물론 상대것을 가져가라고는 안함..)

터닝메카드는 확실히 잘 만든 장난감이고 애니메이션인건 맞다.
실제로 터닝메카드 변신하는거 보면 30대인 나도 설레니까…
근데 동심을 농락해서 돈을 벌어가려는 어른들이 상술이 눈살을 찌푸리게 한다.

[Unity3D] RaycastHit2D

void Update () {

        Debug.DrawRay(transform.position, Vector3.forward, Color.red, 50.0f);

        RaycastHit2D hit =  Physics2D.Raycast(transform.position, Vector3.forward, 50.0f);

        if (hit.collider != null && hit.collider.name != lastCollName)
        {
            lastCollName = hit.collider.name;
            Debug.Log(string.Format("[RaycastHit2D] {0}:{1}", transform.parent.name, hit.collider.name));         
        }
        
	}

[Unity3D] Spine importing with TK2D(2DToolkit)

http://www.youtube.com/watch?v=7dg9slk9mxA

http://ko.esotericsoftware.com/forum/viewtopic.php?f=3&t=3318

 

Spine importing with TK2D

2DToolkit 에서 Spine애니메이션 가져오기

1. Spine 에서 Json 파일을 Export 한다.

2. Spine Runtime 중 Spine-Csharp 과 Spine- tk2d 을 유니티 Assets 안에 추가한다.(폴더 상관없음)

3. Spine 에서 애니메이션을 만들때 사용한 이미지들을 그대로 가져와 tk2d Sprite Collection을 만든다.

4.Json 파일과  Sprite Collection 파일을 동시에 선택 후

우클릭 – Create – Spine – Skeletondata form Selection  를 선택하면

Skeletondata가 생성된다.

5.  SkeletonData 를 우클릭 – Spine – Spawn 하면 SkeletonAnimation Object가 생성된다.

 

 

끝.

 

 

 

[Unity3D] TimeScale 의 영향을 받지 않는 particale

파티클은 유니티 엔진에서 컨트롤을 하기 때문에

TimeScale 이 0인 경우에는 동작하지 않는다.

이를 해결 하려면 다음 스크립트를 파티클 오브젝트에 추가한다.

 

 

using UnityEngine;
using System.Collections;

public class ParticaleAnimator : MonoBehaviour
{

    private void Awake()
    {
        particle = GetComponent<ParticleSystem>();
    }

    // Use this for initialization
    void Start()
    {
        lastTime = Time.realtimeSinceStartup;
    }

    // Update is called once per frame
    void Update()
    {

        float deltaTime = Time.realtimeSinceStartup - (float)lastTime;

        particle.Simulate(deltaTime, true, false); //last must be false!!

        lastTime = Time.realtimeSinceStartup;
    }

    private double lastTime;
    private ParticleSystem particle;

}

[VS2013] CRLF/ LF 개행문자 자동 변환

비주얼 스크립트로 작성된 코드를 유니티에 적용하면 콘솔창에 경고가 보이는 경우가 있다.

이 이유는 유니티의 모노디벨롭은 유닉스 기반이라 개행 문자를 LF 방식을 사용하는데 반해

VS는 CRLF 방식을 사용하기 때문이다.

이것을 해결해주는 간단한 플러그인이 있어서 소개하본다.

사용법과 설명은 링크 참고.

물론 영어.. ㄷㄷㄷㄷ

http://www.grebulon.com/software/stripem.php

그림대로만 따라하면 되고

다운로드는

Download

You can download the Add-in and the source code separately:
 Add-in only – installer for VS 2013 (thanks to Turing Eret), Source code
 Add-in only – installer for VS 2012 (and 2010), Source code
 Add-in only – installer for VS 2008installer for VS 2010 (older version), Source code
 Add-in only – for VS 6Source code

 

여기서 Add-in only 를 클릭하면 된다.

설치는 더블클릭.

 

끝~

Android – BLE Scan Example

package com.example.android.bluetoothlegatt;

import android.app.Activity;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;

public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;

private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getActionBar().setTitle(R.string.title_devices);
    mHandler = new Handler();

    // Use this check to determine whether BLE is supported on the device.  Then you can
    // selectively disable BLE-related features.
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
        Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
        finish();
    }
    // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
    // BluetoothAdapter through BluetoothManager.
    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    // Checks if Bluetooth is supported on the device.
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    if (!mScanning) {
        menu.findItem(R.id.menu_stop).setVisible(false);
        menu.findItem(R.id.menu_scan).setVisible(true);
        menu.findItem(R.id.menu_refresh).setActionView(null);
    } else {
        menu.findItem(R.id.menu_stop).setVisible(true);
        menu.findItem(R.id.menu_scan).setVisible(false);
        menu.findItem(R.id.menu_refresh).setActionView(
                R.layout.actionbar_indeterminate_progress);
    }
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_scan:
            mLeDeviceListAdapter.clear();
            scanLeDevice(true);
            break;
        case R.id.menu_stop:
            scanLeDevice(false);
            break;
    }
    return true;
}

@Override
protected void onResume() {
    super.onResume();
    // Ensures Bluetooth is enabled on the device.  If Bluetooth is not currently enabled,
    // fire an intent to display a dialog asking the user to grant permission to enable it.
    if (!mBluetoothAdapter.isEnabled()) {
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
    }
    // Initializes list view adapter.
    mLeDeviceListAdapter = new LeDeviceListAdapter();
    setListAdapter(mLeDeviceListAdapter);
    scanLeDevice(true);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // User chose not to enable Bluetooth.
    if (requestCode == REQUEST_ENABLE_BT &amp;&amp; resultCode == Activity.RESULT_CANCELED) {
        finish();
        return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

@Override
protected void onPause() {
    super.onPause();
    scanLeDevice(false);
    mLeDeviceListAdapter.clear();
}

private void scanLeDevice(final boolean enable) {
    if (enable) {
        // Stops scanning after a pre-defined scan period.
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScanning = false;
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
                invalidateOptionsMenu();
            }
        }, SCAN_PERIOD);
        mScanning = true;
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    } else {
        mScanning = false;
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
    invalidateOptionsMenu();
}

// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
    private ArrayList&lt;BluetoothDevice&gt; mLeDevices;
    private LayoutInflater mInflator;

    public LeDeviceListAdapter() {
        super();
        mLeDevices = new ArrayList&lt;BluetoothDevice&gt;();
        mInflator = DeviceScanActivity.this.getLayoutInflater();
    }

    public void addDevice(BluetoothDevice device) {
        if(!mLeDevices.contains(device)) {
            mLeDevices.add(device);
        }
    }

    public BluetoothDevice getDevice(int position) {
        return mLeDevices.get(position);
    }

    public void clear() {
        mLeDevices.clear();
    }

    @Override
    public int getCount() {
        return mLeDevices.size();
    }

    @Override
    public Object getItem(int i) {
        return mLeDevices.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder;
        // General ListView optimization code.
        if (view == null) {
            view = mInflator.inflate(R.layout.listitem_device, null);
            viewHolder = new ViewHolder();
            viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
            viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }

        BluetoothDevice device = mLeDevices.get(i);
        final String deviceName = device.getName();
        if (deviceName != null &amp;&amp; deviceName.length() &gt; 0)
            viewHolder.deviceName.setText(deviceName);
        else
            viewHolder.deviceName.setText(R.string.unknown_device);
        viewHolder.deviceAddress.setText(device.getAddress());

        return view;
    }
}

// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
        new BluetoothAdapter.LeScanCallback() {

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mLeDeviceListAdapter.addDevice(device);
                mLeDeviceListAdapter.notifyDataSetChanged();
            }
        });
    }
};

static class ViewHolder {
    TextView deviceName;
    TextView deviceAddress;
}

http://android-er.blogspot.kr/2011/05/scan-bluetooth-devices.html

www.tedhome.net